diff options
-rw-r--r-- | llvm/test/Transforms/InstSimplify/constfold-constrained.ll | 46 | ||||
-rw-r--r-- | llvm/unittests/IR/IRBuilderTest.cpp | 106 |
2 files changed, 120 insertions, 32 deletions
diff --git a/llvm/test/Transforms/InstSimplify/constfold-constrained.ll b/llvm/test/Transforms/InstSimplify/constfold-constrained.ll index 78cba90..a232b49 100644 --- a/llvm/test/Transforms/InstSimplify/constfold-constrained.ll +++ b/llvm/test/Transforms/InstSimplify/constfold-constrained.ll @@ -17,7 +17,7 @@ entry: define double @floor_02() #0 { ; CHECK-LABEL: @floor_02( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.floor.f64(double -1.010000e+01, metadata !"fpexcept.strict") #[[ATTR3:[0-9]+]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.floor.f64(double -1.010000e+01, metadata !"fpexcept.strict") #[[ATTR0:[0-9]+]] ; CHECK-NEXT: ret double -1.100000e+01 ; entry: @@ -40,7 +40,7 @@ entry: define double @ceil_02() #0 { ; CHECK-LABEL: @ceil_02( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.ceil.f64(double -1.010000e+01, metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.ceil.f64(double -1.010000e+01, metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double -1.000000e+01 ; entry: @@ -63,11 +63,11 @@ entry: define double @trunc_02() #0 { ; CHECK-LABEL: @trunc_02( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double -1.010000e+01) #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double -1.010000e+01) #0 [ "fp.except"(metadata !"strict") ] ; CHECK-NEXT: ret double -1.000000e+01 ; entry: - %result = call double @llvm.trunc.f64(double -1.010000e+01, metadata !"fpexcept.strict") #0 [ "fp.except"(metadata !"strict") ] + %result = call double @llvm.trunc.f64(double -1.010000e+01) #0 [ "fp.except"(metadata !"strict") ] ret double %result } @@ -86,7 +86,7 @@ entry: define double @round_02() #0 { ; CHECK-LABEL: @round_02( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.round.f64(double -1.050000e+01, metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.round.f64(double -1.050000e+01, metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double -1.100000e+01 ; entry: @@ -120,7 +120,7 @@ entry: define double @nearbyint_03() #0 { ; CHECK-LABEL: @nearbyint_03( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.towardzero", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"rtz"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.towardzero", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double 1.000000e+01 ; entry: @@ -132,7 +132,7 @@ entry: define double @nearbyint_04() #0 { ; CHECK-LABEL: @nearbyint_04( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"rte"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double 1.000000e+01 ; entry: @@ -144,7 +144,7 @@ entry: define double @nearbyint_05() #0 { ; CHECK-LABEL: @nearbyint_05( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"dyn"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.nearbyint.f64(double 1.050000e+01, metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double [[RESULT]] ; entry: @@ -156,11 +156,11 @@ entry: define double @nonfinite_01() #0 { ; CHECK-LABEL: @nonfinite_01( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double 0x7FF4000000000000) #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double 0x7FF4000000000000) #0 [ "fp.except"(metadata !"strict") ] ; CHECK-NEXT: ret double [[RESULT]] ; entry: - %result = call double @llvm.trunc.f64(double 0x7ff4000000000000, metadata !"fpexcept.strict") #0 [ "fp.except"(metadata !"strict") ] + %result = call double @llvm.trunc.f64(double 0x7ff4000000000000) #0 [ "fp.except"(metadata !"strict") ] ret double %result } @@ -179,7 +179,7 @@ entry: define double @nonfinite_03() #0 { ; CHECK-LABEL: @nonfinite_03( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double 0x7FF8000000000000) #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double 0x7FF8000000000000) #0 [ "fp.except"(metadata !"strict") ] ; CHECK-NEXT: ret double 0x7FF8000000000000 ; entry: @@ -191,7 +191,7 @@ entry: define double @nonfinite_04() #0 { ; CHECK-LABEL: @nonfinite_04( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double 0x7FF0000000000000) #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.trunc.f64(double 0x7FF0000000000000) #0 [ "fp.except"(metadata !"strict") ] ; CHECK-NEXT: ret double 0x7FF0000000000000 ; entry: @@ -203,7 +203,7 @@ entry: define double @rint_01() #0 { ; CHECK-LABEL: @rint_01( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.rint.f64(double 1.000000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"rte"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.rint.f64(double 1.000000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double 1.000000e+01 ; entry: @@ -215,7 +215,7 @@ entry: define double @rint_02() #0 { ; CHECK-LABEL: @rint_02( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.rint.f64(double 1.010000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"rte"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.rint.f64(double 1.010000e+01, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double [[RESULT]] ; entry: @@ -270,7 +270,7 @@ entry: define double @fadd_04() #0 { ; CHECK-LABEL: @fadd_04( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 0x3FF0000000000001, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"rte"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 0x3FF0000000000001, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double [[RESULT]] ; entry: @@ -282,7 +282,7 @@ entry: define double @fadd_05() #0 { ; CHECK-LABEL: @fadd_05( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 2.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"rte"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 2.000000e+00, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double 3.000000e+00 ; entry: @@ -294,7 +294,7 @@ entry: define double @fadd_06() #0 { ; CHECK-LABEL: @fadd_06( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 2.000000e+00, metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"dyn"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 2.000000e+00, metadata !"round.dynamic", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double 3.000000e+00 ; entry: @@ -306,7 +306,7 @@ entry: define double @fadd_07() #0 { ; CHECK-LABEL: @fadd_07( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 0x3FF0000000000001, metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR3]] [ "fp.control"(metadata !"dyn"), "fp.except"(metadata !"ignore") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 1.000000e+00, double 0x3FF0000000000001, metadata !"round.dynamic", metadata !"fpexcept.ignore") #[[ATTR0]] ; CHECK-NEXT: ret double [[RESULT]] ; entry: @@ -328,7 +328,7 @@ entry: define double @fadd_09() #0 { ; CHECK-LABEL: @fadd_09( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 0x7FEFFFFFFFFFFFFF, double 0x7FEFFFFFFFFFFFFF, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.control"(metadata !"rte"), "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call double @llvm.experimental.constrained.fadd.f64(double 0x7FEFFFFFFFFFFFFF, double 0x7FEFFFFFFFFFFFFF, metadata !"round.tonearest", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret double [[RESULT]] ; entry: @@ -492,7 +492,7 @@ entry: define i1 @cmp_eq_nan_01() #0 { ; CHECK-LABEL: @cmp_eq_nan_01( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7FF4000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7FF4000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret i1 [[RESULT]] ; entry: @@ -503,7 +503,7 @@ entry: define i1 @cmp_eq_nan_02() #0 { ; CHECK-LABEL: @cmp_eq_nan_02( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 0x7FF4000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 0x7FF4000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret i1 [[RESULT]] ; entry: @@ -515,7 +515,7 @@ entry: define i1 @cmp_eq_nan_03() #0 { ; CHECK-LABEL: @cmp_eq_nan_03( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7FF8000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmp.f64(double 0x7FF8000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret i1 false ; entry: @@ -526,7 +526,7 @@ entry: define i1 @cmp_eq_nan_04() #0 { ; CHECK-LABEL: @cmp_eq_nan_04( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 0x7FF8000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR3]] [ "fp.except"(metadata !"strict") ] +; CHECK-NEXT: [[RESULT:%.*]] = call i1 @llvm.experimental.constrained.fcmps.f64(double 0x7FF8000000000000, double 1.000000e+00, metadata !"oeq", metadata !"fpexcept.strict") #[[ATTR0]] ; CHECK-NEXT: ret i1 [[RESULT]] ; entry: diff --git a/llvm/unittests/IR/IRBuilderTest.cpp b/llvm/unittests/IR/IRBuilderTest.cpp index 6b38a58..0e59ba0 100644 --- a/llvm/unittests/IR/IRBuilderTest.cpp +++ b/llvm/unittests/IR/IRBuilderTest.cpp @@ -402,11 +402,57 @@ TEST_F(IRBuilderTest, ConstrainedFP) { EXPECT_FALSE(verifyModule(*M)); } +// Check call creation in strictfp function if the builder object does not +// specify default values for rounding and exception behavior. +TEST_F(IRBuilderTest, StrictFPCallDefault) { + F->addFnAttr(Attribute::StrictFP); + + IRBuilder<> Builder(BB); + Builder.setIsFPConstrained(true); + + GlobalVariable *GVDouble = new GlobalVariable( + *M, Type::getDoubleTy(Ctx), true, GlobalValue::ExternalLinkage, nullptr); + Value *FnArg = Builder.CreateLoad(GVDouble->getValueType(), GVDouble); + Function *Fn = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::trunc, + {Type::getDoubleTy(Ctx)}); + + // Function call without explicit bundles. By default it has strict exception + // behavior. + CallInst *CI = Builder.CreateCall(Fn, {FnArg}); + EXPECT_EQ(Intrinsic::trunc, CI->getIntrinsicID()); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_control).has_value()); + EXPECT_TRUE(CI->getOperandBundle(LLVMContext::OB_fp_except).has_value()); + std::optional<RoundingMode> RM = CI->getRoundingMode(); + EXPECT_FALSE(RM.has_value()); + std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior(); + EXPECT_TRUE(EB.has_value()); + EXPECT_EQ(fp::ebStrict, *EB); + EXPECT_TRUE(CI->getMemoryEffects().doesAccessInaccessibleMem()); + + // Function call with explicit bundles. + SmallVector<OperandBundleDef, 2> OpBundles; + Builder.createFPExceptionBundle(OpBundles, fp::ebIgnore); + CI = Builder.CreateCall(Fn, {FnArg}, OpBundles); + EXPECT_EQ(Intrinsic::trunc, CI->getIntrinsicID()); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_control).has_value()); + EXPECT_TRUE(CI->getOperandBundle(LLVMContext::OB_fp_except).has_value()); + RM = CI->getRoundingMode(); + EXPECT_FALSE(RM.has_value()); + RoundingMode Rounding = CI->getRoundingMode().value_or(RoundingMode::Dynamic); + EXPECT_EQ(RoundingMode::Dynamic, Rounding); + EB = CI->getExceptionBehavior(); + EXPECT_TRUE(EB.has_value()); + EXPECT_EQ(fp::ebIgnore, *EB); + EXPECT_TRUE(CI->getMemoryEffects().doesAccessInaccessibleMem()); +} + +// Check call creation in strictfp function if the builder object specifies +// default values for rounding and exception behavior. TEST_F(IRBuilderTest, StrictFPCall) { F->addFnAttr(Attribute::StrictFP); IRBuilder<> Builder(BB); - Builder.setDefaultConstrainedExcept(fp::ebStrict); + Builder.setDefaultConstrainedExcept(fp::ebIgnore); Builder.setDefaultConstrainedRounding(RoundingMode::TowardZero); Builder.setIsFPConstrained(true); @@ -416,7 +462,33 @@ TEST_F(IRBuilderTest, StrictFPCall) { // Function calls, that may depend on FP options, gets fp bundles in strictfp // environment. - Function *Fn = Intrinsic::getOrInsertDeclaration( + Function *Fn = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::trunc, + {Type::getDoubleTy(Ctx)}); + CallInst *CI = Builder.CreateCall(Fn, {FnArg}); + EXPECT_EQ(Intrinsic::trunc, CI->getIntrinsicID()); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_control).has_value()); + EXPECT_TRUE(CI->getOperandBundle(LLVMContext::OB_fp_except).has_value()); + std::optional<RoundingMode> RM = CI->getRoundingMode(); + EXPECT_FALSE(RM.has_value()); + std::optional<fp::ExceptionBehavior> EB = CI->getExceptionBehavior(); + EXPECT_TRUE(EB.has_value()); + EXPECT_EQ(fp::ebIgnore, *EB); + EXPECT_TRUE(CI->getMemoryEffects().doesAccessInaccessibleMem()); + + // Explicit bundle arguments override builder default values. + SmallVector<OperandBundleDef, 2> OpBundles; + Builder.createFPExceptionBundle(OpBundles, fp::ebIgnore); + CI = Builder.CreateCall(Fn, {FnArg}, OpBundles); + EXPECT_EQ(Intrinsic::trunc, CI->getIntrinsicID()); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_control).has_value()); + EXPECT_TRUE(CI->getOperandBundle(LLVMContext::OB_fp_except).has_value()); + EB = CI->getExceptionBehavior(); + EXPECT_TRUE(EB.has_value()); + EXPECT_EQ(fp::ebIgnore, *EB); + EXPECT_TRUE(CI->getMemoryEffects().doesAccessInaccessibleMem()); + + // Legacy constrained intrinsic call. + Fn = Intrinsic::getOrInsertDeclaration( M.get(), Intrinsic::experimental_constrained_roundeven, {Type::getDoubleTy(Ctx)}); Value *V = Builder.CreateConstrainedFPCall(Fn, {FnArg}); @@ -424,7 +496,7 @@ TEST_F(IRBuilderTest, StrictFPCall) { EXPECT_TRUE(I->getOperandBundle(LLVMContext::OB_fp_except).has_value()); EXPECT_FALSE(I->getOperandBundle(LLVMContext::OB_fp_control).has_value()); EXPECT_EQ(Intrinsic::experimental_constrained_roundeven, I->getIntrinsicID()); - EXPECT_EQ(fp::ebStrict, I->getExceptionBehavior()); + EXPECT_EQ(fp::ebIgnore, I->getExceptionBehavior()); MemoryEffects ME = I->getMemoryEffects(); EXPECT_TRUE(ME.doesAccessInaccessibleMem()); @@ -432,12 +504,28 @@ TEST_F(IRBuilderTest, StrictFPCall) { // fp bundles. Fn = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::fabs, {Type::getDoubleTy(Ctx)}); - V = Builder.CreateCall(Fn, {FnArg}); - I = cast<IntrinsicInst>(V); - EXPECT_FALSE(I->getOperandBundle(LLVMContext::OB_fp_except).has_value()); - EXPECT_FALSE(I->getOperandBundle(LLVMContext::OB_fp_control).has_value()); - ME = I->getMemoryEffects(); - EXPECT_FALSE(ME.doesAccessInaccessibleMem()); + CI = Builder.CreateCall(Fn, {FnArg}); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_except).has_value()); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_control).has_value()); + EXPECT_FALSE(CI->getMemoryEffects().doesAccessInaccessibleMem()); +} + +TEST_F(IRBuilderTest, FPMemoryEffects) { + IRBuilder<> Builder(BB); + GlobalVariable *GVDouble = new GlobalVariable( + *M, Type::getDoubleTy(Ctx), true, GlobalValue::ExternalLinkage, nullptr); + Value *FnArg = Builder.CreateLoad(GVDouble->getValueType(), GVDouble); + Function *Fn = Intrinsic::getOrInsertDeclaration(M.get(), Intrinsic::trunc, + {Type::getDoubleTy(Ctx)}); + + CallInst *CI = Builder.CreateCall(Fn, {FnArg}); + EXPECT_EQ(Intrinsic::trunc, CI->getIntrinsicID()); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_control).has_value()); + EXPECT_FALSE(CI->getOperandBundle(LLVMContext::OB_fp_except).has_value()); + EXPECT_TRUE(CI->getMemoryEffects().doesNotAccessMemory()); + + F->addFnAttr(Attribute::StrictFP); + EXPECT_TRUE(CI->getMemoryEffects().doesAccessInaccessibleMem()); } TEST_F(IRBuilderTest, ConstrainedFPIntrinsics) { |