| 3752 | return {}; |
| 3753 | } |
| 3754 | void compileSignedTrunc(LLVM::Type IntType) noexcept { |
| 3755 | auto NormBB = LLVM::BasicBlock::create(LLContext, F.Fn, "strunc.norm"); |
| 3756 | auto NotMinBB = LLVM::BasicBlock::create(LLContext, F.Fn, "strunc.notmin"); |
| 3757 | auto NotMaxBB = LLVM::BasicBlock::create(LLContext, F.Fn, "strunc.notmax"); |
| 3758 | auto Value = stackPop(); |
| 3759 | const auto [Precise, MinFp, MaxFp] = |
| 3760 | [IntType, Value]() -> std::tuple<bool, LLVM::Value, LLVM::Value> { |
| 3761 | const auto BitWidth = IntType.getIntegerBitWidth(); |
| 3762 | const auto [Min, Max] = [BitWidth]() -> std::tuple<int64_t, int64_t> { |
| 3763 | switch (BitWidth) { |
| 3764 | case 32: |
| 3765 | return {std::numeric_limits<int32_t>::min(), |
| 3766 | std::numeric_limits<int32_t>::max()}; |
| 3767 | case 64: |
| 3768 | return {std::numeric_limits<int64_t>::min(), |
| 3769 | std::numeric_limits<int64_t>::max()}; |
| 3770 | default: |
| 3771 | assumingUnreachable(); |
| 3772 | } |
| 3773 | }(); |
| 3774 | auto FPType = Value.getType(); |
| 3775 | assuming(FPType.isFloatTy() || FPType.isDoubleTy()); |
| 3776 | const auto FPWidth = FPType.getFPMantissaWidth(); |
| 3777 | return {BitWidth <= FPWidth, LLVM::Value::getConstReal(FPType, Min), |
| 3778 | LLVM::Value::getConstReal(FPType, Max)}; |
| 3779 | }(); |
| 3780 | |
| 3781 | auto IsNotNan = Builder.createLikely(Builder.createFCmpORD(Value, Value)); |
| 3782 | Builder.createCondBr(IsNotNan, NormBB, |
| 3783 | getTrapBB(ErrCode::Value::InvalidConvToInt)); |
| 3784 | |
| 3785 | Builder.positionAtEnd(NormBB); |
| 3786 | assuming(LLVM::Core::Trunc != LLVM::Core::NotIntrinsic); |
| 3787 | auto Trunc = Builder.createUnaryIntrinsic(LLVM::Core::Trunc, Value); |
| 3788 | auto IsNotUnderflow = |
| 3789 | Builder.createLikely(Builder.createFCmpOGE(Trunc, MinFp)); |
| 3790 | Builder.createCondBr(IsNotUnderflow, NotMinBB, |
| 3791 | getTrapBB(ErrCode::Value::IntegerOverflow)); |
| 3792 | |
| 3793 | Builder.positionAtEnd(NotMinBB); |
| 3794 | auto IsNotOverflow = Builder.createLikely( |
| 3795 | Builder.createFCmp(Precise ? LLVMRealOLE : LLVMRealOLT, Trunc, MaxFp)); |
| 3796 | Builder.createCondBr(IsNotOverflow, NotMaxBB, |
| 3797 | getTrapBB(ErrCode::Value::IntegerOverflow)); |
| 3798 | |
| 3799 | Builder.positionAtEnd(NotMaxBB); |
| 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"); |
nothing calls this directly
no test coverage detected