| 3908 | stackPush(Builder.createFPToUI(Trunc, IntType)); |
| 3909 | } |
| 3910 | void compileUnsignedTruncSat(LLVM::Type IntType) noexcept { |
| 3911 | auto CurrBB = Builder.getInsertBlock(); |
| 3912 | auto NormBB = LLVM::BasicBlock::create(LLContext, F.Fn, "usat.norm"); |
| 3913 | auto NotMaxBB = LLVM::BasicBlock::create(LLContext, F.Fn, "usat.notmax"); |
| 3914 | auto EndBB = LLVM::BasicBlock::create(LLContext, F.Fn, "usat.end"); |
| 3915 | auto Value = stackPop(); |
| 3916 | const auto [Precise, MinInt, MaxInt, MinFp, MaxFp] = [IntType, Value]() |
| 3917 | -> std::tuple<bool, uint64_t, uint64_t, LLVM::Value, LLVM::Value> { |
| 3918 | const auto BitWidth = IntType.getIntegerBitWidth(); |
| 3919 | const auto [Min, Max] = [BitWidth]() -> std::tuple<uint64_t, uint64_t> { |
| 3920 | switch (BitWidth) { |
| 3921 | case 32: |
| 3922 | return {std::numeric_limits<uint32_t>::min(), |
| 3923 | std::numeric_limits<uint32_t>::max()}; |
| 3924 | case 64: |
| 3925 | return {std::numeric_limits<uint64_t>::min(), |
| 3926 | std::numeric_limits<uint64_t>::max()}; |
| 3927 | default: |
| 3928 | assumingUnreachable(); |
| 3929 | } |
| 3930 | }(); |
| 3931 | auto FPType = Value.getType(); |
| 3932 | assuming(FPType.isFloatTy() || FPType.isDoubleTy()); |
| 3933 | const auto FPWidth = FPType.getFPMantissaWidth(); |
| 3934 | return {BitWidth <= FPWidth, Min, Max, |
| 3935 | LLVM::Value::getConstReal(FPType, Min), |
| 3936 | LLVM::Value::getConstReal(FPType, Max)}; |
| 3937 | }(); |
| 3938 | |
| 3939 | assuming(LLVM::Core::Trunc != LLVM::Core::NotIntrinsic); |
| 3940 | auto Trunc = Builder.createUnaryIntrinsic(LLVM::Core::Trunc, Value); |
| 3941 | auto IsNotUnderflow = |
| 3942 | Builder.createLikely(Builder.createFCmpOGE(Trunc, MinFp)); |
| 3943 | Builder.createCondBr(IsNotUnderflow, NormBB, EndBB); |
| 3944 | |
| 3945 | Builder.positionAtEnd(NormBB); |
| 3946 | auto IsNotOverflow = Builder.createLikely( |
| 3947 | Builder.createFCmp(Precise ? LLVMRealOLE : LLVMRealOLT, Trunc, MaxFp)); |
| 3948 | Builder.createCondBr(IsNotOverflow, NotMaxBB, EndBB); |
| 3949 | |
| 3950 | Builder.positionAtEnd(NotMaxBB); |
| 3951 | auto IntValue = Builder.createFPToUI(Trunc, IntType); |
| 3952 | Builder.createBr(EndBB); |
| 3953 | |
| 3954 | Builder.positionAtEnd(EndBB); |
| 3955 | auto PHIRet = Builder.createPHI(IntType); |
| 3956 | PHIRet.addIncoming(LLVM::Value::getConstInt(IntType, MinInt), CurrBB); |
| 3957 | PHIRet.addIncoming(LLVM::Value::getConstInt(IntType, MaxInt), NormBB); |
| 3958 | PHIRet.addIncoming(IntValue, NotMaxBB); |
| 3959 | |
| 3960 | stackPush(PHIRet); |
| 3961 | } |
| 3962 | |
| 3963 | void compileAtomicCheckOffsetAlignment(LLVM::Value Offset, |
| 3964 | LLVM::Type IntType) noexcept { |
nothing calls this directly
no test coverage detected