aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--llvm/test/Transforms/InstSimplify/constfold-constrained.ll46
-rw-r--r--llvm/unittests/IR/IRBuilderTest.cpp106
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) {