MCPcopy Create free account
hub / github.com/WasmEdge/WasmEdge / compileSignedTruncSat

Method compileSignedTruncSat

lib/llvm/compiler.cpp:3802–3861  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3800 stackPush(Builder.createFPToSI(Trunc, IntType));
3801 }
3802 void compileSignedTruncSat(LLVM::Type IntType) noexcept {
3803 auto CurrBB = Builder.getInsertBlock();
3804 auto NormBB = LLVM::BasicBlock::create(LLContext, F.Fn, "ssat.norm");
3805 auto NotMinBB = LLVM::BasicBlock::create(LLContext, F.Fn, "ssat.notmin");
3806 auto NotMaxBB = LLVM::BasicBlock::create(LLContext, F.Fn, "ssat.notmax");
3807 auto EndBB = LLVM::BasicBlock::create(LLContext, F.Fn, "ssat.end");
3808 auto Value = stackPop();
3809 const auto [Precise, MinInt, MaxInt, MinFp, MaxFp] = [IntType, Value]()
3810 -> std::tuple<bool, uint64_t, uint64_t, LLVM::Value, LLVM::Value> {
3811 const auto BitWidth = IntType.getIntegerBitWidth();
3812 const auto [Min, Max] = [BitWidth]() -> std::tuple<int64_t, int64_t> {
3813 switch (BitWidth) {
3814 case 32:
3815 return {std::numeric_limits<int32_t>::min(),
3816 std::numeric_limits<int32_t>::max()};
3817 case 64:
3818 return {std::numeric_limits<int64_t>::min(),
3819 std::numeric_limits<int64_t>::max()};
3820 default:
3821 assumingUnreachable();
3822 }
3823 }();
3824 auto FPType = Value.getType();
3825 assuming(FPType.isFloatTy() || FPType.isDoubleTy());
3826 const auto FPWidth = FPType.getFPMantissaWidth();
3827 return {BitWidth <= FPWidth, static_cast<uint64_t>(Min),
3828 static_cast<uint64_t>(Max),
3829 LLVM::Value::getConstReal(FPType, Min),
3830 LLVM::Value::getConstReal(FPType, Max)};
3831 }();
3832
3833 auto IsNotNan = Builder.createLikely(Builder.createFCmpORD(Value, Value));
3834 Builder.createCondBr(IsNotNan, NormBB, EndBB);
3835
3836 Builder.positionAtEnd(NormBB);
3837 assuming(LLVM::Core::Trunc != LLVM::Core::NotIntrinsic);
3838 auto Trunc = Builder.createUnaryIntrinsic(LLVM::Core::Trunc, Value);
3839 auto IsNotUnderflow =
3840 Builder.createLikely(Builder.createFCmpOGE(Trunc, MinFp));
3841 Builder.createCondBr(IsNotUnderflow, NotMinBB, EndBB);
3842
3843 Builder.positionAtEnd(NotMinBB);
3844 auto IsNotOverflow = Builder.createLikely(
3845 Builder.createFCmp(Precise ? LLVMRealOLE : LLVMRealOLT, Trunc, MaxFp));
3846 Builder.createCondBr(IsNotOverflow, NotMaxBB, EndBB);
3847
3848 Builder.positionAtEnd(NotMaxBB);
3849 auto IntValue = Builder.createFPToSI(Trunc, IntType);
3850 Builder.createBr(EndBB);
3851
3852 Builder.positionAtEnd(EndBB);
3853 auto PHIRet = Builder.createPHI(IntType);
3854 PHIRet.addIncoming(LLVM::Value::getConstInt(IntType, 0, true), CurrBB);
3855 PHIRet.addIncoming(LLVM::Value::getConstInt(IntType, MinInt, true), NormBB);
3856 PHIRet.addIncoming(LLVM::Value::getConstInt(IntType, MaxInt, true),
3857 NotMinBB);
3858 PHIRet.addIncoming(IntValue, NotMaxBB);
3859

Callers

nothing calls this directly

Calls 15

getInsertBlockMethod · 0.80
getIntegerBitWidthMethod · 0.80
isFloatTyMethod · 0.80
isDoubleTyMethod · 0.80
getFPMantissaWidthMethod · 0.80
createLikelyMethod · 0.80
createFCmpORDMethod · 0.80
createCondBrMethod · 0.80
positionAtEndMethod · 0.80
createUnaryIntrinsicMethod · 0.80
createFCmpOGEMethod · 0.80
createFCmpMethod · 0.80

Tested by

no test coverage detected