[FPEnv] Teach the IRBuilder about correct use of the strictfp attribute.

The IRBuilder needs to add the strictfp attribute to function
definitions and calls when constrained floating point is enabled.

Since so far all front ends have had to do is flip the constrained
switch, I've made this patch always add the required attributes
when said constrained switch is enabled. This continues to keep
changes to front ends minimal.

Differential Revision: D69312
This commit is contained in:
Kevin P. Neal 2019-10-22 13:07:15 -04:00
parent a153233caf
commit de79836312
2 changed files with 31 additions and 0 deletions

View File

@ -255,6 +255,21 @@ public:
return DefaultConstrainedRounding;
}
void setConstrainedFPFunctionAttr() {
assert(BB && "Must have a basic block to set any function attributes!");
Function *F = BB->getParent();
if (!F->hasFnAttribute(Attribute::StrictFP)) {
F->addFnAttr(Attribute::StrictFP);
}
}
void setConstrainedFPCallAttr(CallInst *I) {
if (!I->hasFnAttr(Attribute::StrictFP))
I->addAttribute(AttributeList::FunctionIndex, Attribute::StrictFP);
setConstrainedFPFunctionAttr();
}
//===--------------------------------------------------------------------===//
// RAII helpers.
//===--------------------------------------------------------------------===//
@ -1479,6 +1494,7 @@ public:
CallInst *C = CreateIntrinsic(ID, {L->getType()},
{L, R, RoundingV, ExceptV}, nullptr, Name);
setConstrainedFPCallAttr(C);
setFPAttrs(C, FPMathTag, UseFMF);
return C;
}
@ -2084,6 +2100,8 @@ public:
Name);
break;
}
setConstrainedFPCallAttr(C);
if (isa<FPMathOperator>(C))
setFPAttrs(C, FPMathTag, UseFMF);
return C;
@ -2240,6 +2258,8 @@ public:
ArrayRef<Value *> Args = None, const Twine &Name = "",
MDNode *FPMathTag = nullptr) {
CallInst *CI = CallInst::Create(FTy, Callee, Args, DefaultOperandBundles);
if (IsFPConstrained)
setConstrainedFPCallAttr(CI);
if (isa<FPMathOperator>(CI))
setFPAttrs(CI, FPMathTag, FMF);
return Insert(CI, Name);
@ -2249,6 +2269,8 @@ public:
ArrayRef<OperandBundleDef> OpBundles,
const Twine &Name = "", MDNode *FPMathTag = nullptr) {
CallInst *CI = CallInst::Create(FTy, Callee, Args, OpBundles);
if (IsFPConstrained)
setConstrainedFPCallAttr(CI);
if (isa<FPMathOperator>(CI))
setFPAttrs(CI, FPMathTag, FMF);
return Insert(CI, Name);

View File

@ -229,6 +229,15 @@ TEST_F(IRBuilderTest, ConstrainedFP) {
II = cast<IntrinsicInst>(VDouble);
EXPECT_EQ(II->getIntrinsicID(), Intrinsic::experimental_constrained_fpext);
// Verify attributes on the call are created automatically.
AttributeSet CallAttrs = II->getAttributes().getFnAttributes();
EXPECT_EQ(CallAttrs.hasAttribute(Attribute::StrictFP), true);
// Verify attributes on the containing function are created automatically.
AttributeList Attrs = BB->getParent()->getAttributes();
AttributeSet FnAttrs = Attrs.getFnAttributes();
EXPECT_EQ(FnAttrs.hasAttribute(Attribute::StrictFP), true);
// Verify the codepaths for setting and overriding the default metadata.
V = Builder.CreateFAdd(V, V);
ASSERT_TRUE(isa<ConstrainedFPIntrinsic>(V));