Skip to content

Commit 53a5fbb

Browse files
author
Andrew Kaylor
committedAug 14, 2017
Add strictfp attribute to prevent unwanted optimizations of libm calls
Differential Revision: https://reviews.llvm.org/D34163 llvm-svn: 310885
1 parent 8bf1572 commit 53a5fbb

File tree

22 files changed

+172
-83
lines changed

22 files changed

+172
-83
lines changed
 

‎llvm/docs/LangRef.rst

+6
Original file line numberDiff line numberDiff line change
@@ -1644,6 +1644,12 @@ example:
16441644
If a function that has an ``sspstrong`` attribute is inlined into a
16451645
function that doesn't have an ``sspstrong`` attribute, then the
16461646
resulting function will have an ``sspstrong`` attribute.
1647+
``strictfp``
1648+
This attribute indicates that the function was called from a scope that
1649+
requires strict floating point semantics. LLVM will not attempt any
1650+
optimizations that require assumptions about the floating point rounding
1651+
mode or that might alter the state of floating point status flags that
1652+
might otherwise be set or cleared by calling this function.
16471653
``"thunk"``
16481654
This attribute indicates that the function will delegate to some other
16491655
function with a tail call. The prototype of a thunk should not be used for

‎llvm/include/llvm/Bitcode/LLVMBitCodes.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,8 @@ enum AttributeKindCodes {
558558
ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
559559
ATTR_KIND_ALLOC_SIZE = 51,
560560
ATTR_KIND_WRITEONLY = 52,
561-
ATTR_KIND_SPECULATABLE = 53
561+
ATTR_KIND_SPECULATABLE = 53,
562+
ATTR_KIND_STRICT_FP = 54,
562563
};
563564

564565
enum ComdatSelectionKindCodes {

‎llvm/include/llvm/IR/Attributes.td

+3
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ def StackProtectReq : EnumAttr<"sspreq">;
149149
/// Strong Stack protection.
150150
def StackProtectStrong : EnumAttr<"sspstrong">;
151151

152+
/// Function was called in a scope requiring strict floating point semantics.
153+
def StrictFP : EnumAttr<"strictfp">;
154+
152155
/// Hidden pointer to structure to return.
153156
def StructRet : EnumAttr<"sret">;
154157

‎llvm/include/llvm/IR/CallSite.h

+5
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,11 @@ class CallSiteBase {
426426
CALLSITE_DELEGATE_GETTER(isNoBuiltin());
427427
}
428428

429+
/// Return true if the call requires strict floating point semantics.
430+
bool isStrictFP() const {
431+
CALLSITE_DELEGATE_GETTER(isStrictFP());
432+
}
433+
429434
/// Return true if the call should not be inlined.
430435
bool isNoInline() const {
431436
CALLSITE_DELEGATE_GETTER(isNoInline());

‎llvm/include/llvm/IR/Instructions.h

+6
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,9 @@ class CallInst : public Instruction,
17571757
!hasFnAttrImpl(Attribute::Builtin);
17581758
}
17591759

1760+
/// Determine if the call requires strict floating point semantics.
1761+
bool isStrictFP() const { return hasFnAttr(Attribute::StrictFP); }
1762+
17601763
/// Return true if the call should not be inlined.
17611764
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
17621765
void setIsNoInline() {
@@ -3844,6 +3847,9 @@ class InvokeInst : public TerminatorInst,
38443847
!hasFnAttrImpl(Attribute::Builtin);
38453848
}
38463849

3850+
/// Determine if the call requires strict floating point semantics.
3851+
bool isStrictFP() const { return hasFnAttr(Attribute::StrictFP); }
3852+
38473853
/// Return true if the call should not be inlined.
38483854
bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
38493855
void setIsNoInline() {

‎llvm/include/llvm/Transforms/Utils/SimplifyLibCalls.h

+3
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ class LibCallSimplifier {
137137
Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
138138
Value *optimizeSinCosPi(CallInst *CI, IRBuilder<> &B);
139139
Value *optimizeTan(CallInst *CI, IRBuilder<> &B);
140+
// Wrapper for all floating point library call optimizations
141+
Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
142+
IRBuilder<> &B);
140143

141144
// Integer Library Call Optimizations
142145
Value *optimizeFFS(CallInst *CI, IRBuilder<> &B);

‎llvm/lib/Analysis/ConstantFolding.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,7 @@ llvm::ConstantFoldLoadThroughGEPIndices(Constant *C,
13591359
//
13601360

13611361
bool llvm::canConstantFoldCallTo(ImmutableCallSite CS, const Function *F) {
1362-
if (CS.isNoBuiltin())
1362+
if (CS.isNoBuiltin() || CS.isStrictFP())
13631363
return false;
13641364
switch (F->getIntrinsicID()) {
13651365
case Intrinsic::fabs:
@@ -2066,7 +2066,7 @@ Constant *
20662066
llvm::ConstantFoldCall(ImmutableCallSite CS, Function *F,
20672067
ArrayRef<Constant *> Operands,
20682068
const TargetLibraryInfo *TLI) {
2069-
if (CS.isNoBuiltin())
2069+
if (CS.isNoBuiltin() || CS.isStrictFP())
20702070
return nullptr;
20712071
if (!F->hasName())
20722072
return nullptr;
@@ -2084,7 +2084,7 @@ llvm::ConstantFoldCall(ImmutableCallSite CS, Function *F,
20842084
bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
20852085
// FIXME: Refactor this code; this duplicates logic in LibCallsShrinkWrap
20862086
// (and to some extent ConstantFoldScalarCall).
2087-
if (CS.isNoBuiltin())
2087+
if (CS.isNoBuiltin() || CS.isStrictFP())
20882088
return false;
20892089
Function *F = CS.getCalledFunction();
20902090
if (!F)

‎llvm/lib/AsmParser/LLLexer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ lltok::Kind LLLexer::LexIdentifier() {
654654
KEYWORD(ssp);
655655
KEYWORD(sspreq);
656656
KEYWORD(sspstrong);
657+
KEYWORD(strictfp);
657658
KEYWORD(safestack);
658659
KEYWORD(sanitize_address);
659660
KEYWORD(sanitize_thread);

‎llvm/lib/AsmParser/LLParser.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1121,6 +1121,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
11211121
B.addAttribute(Attribute::SanitizeThread); break;
11221122
case lltok::kw_sanitize_memory:
11231123
B.addAttribute(Attribute::SanitizeMemory); break;
1124+
case lltok::kw_strictfp: B.addAttribute(Attribute::StrictFP); break;
11241125
case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
11251126
case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
11261127

@@ -1446,6 +1447,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
14461447
case lltok::kw_sspreq:
14471448
case lltok::kw_sspstrong:
14481449
case lltok::kw_safestack:
1450+
case lltok::kw_strictfp:
14491451
case lltok::kw_uwtable:
14501452
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
14511453
break;
@@ -1537,6 +1539,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
15371539
case lltok::kw_sspreq:
15381540
case lltok::kw_sspstrong:
15391541
case lltok::kw_safestack:
1542+
case lltok::kw_strictfp:
15401543
case lltok::kw_uwtable:
15411544
HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
15421545
break;

‎llvm/lib/AsmParser/LLToken.h

+1
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ enum Kind {
207207
kw_sret,
208208
kw_sanitize_thread,
209209
kw_sanitize_memory,
210+
kw_strictfp,
210211
kw_swifterror,
211212
kw_swiftself,
212213
kw_uwtable,

‎llvm/lib/Bitcode/Reader/BitcodeReader.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,7 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) {
11371137
case Attribute::SwiftError: return 1ULL << 52;
11381138
case Attribute::WriteOnly: return 1ULL << 53;
11391139
case Attribute::Speculatable: return 1ULL << 54;
1140+
case Attribute::StrictFP: return 1ULL << 55;
11401141
case Attribute::Dereferenceable:
11411142
llvm_unreachable("dereferenceable attribute not supported in raw format");
11421143
break;
@@ -1345,6 +1346,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
13451346
return Attribute::StackProtectStrong;
13461347
case bitc::ATTR_KIND_SAFESTACK:
13471348
return Attribute::SafeStack;
1349+
case bitc::ATTR_KIND_STRICT_FP:
1350+
return Attribute::StrictFP;
13481351
case bitc::ATTR_KIND_STRUCT_RET:
13491352
return Attribute::StructRet;
13501353
case bitc::ATTR_KIND_SANITIZE_ADDRESS:

‎llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
610610
return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
611611
case Attribute::SafeStack:
612612
return bitc::ATTR_KIND_SAFESTACK;
613+
case Attribute::StrictFP:
614+
return bitc::ATTR_KIND_STRICT_FP;
613615
case Attribute::StructRet:
614616
return bitc::ATTR_KIND_STRUCT_RET;
615617
case Attribute::SanitizeAddress:

‎llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -6555,10 +6555,10 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
65556555

65566556
// Check for well-known libc/libm calls. If the function is internal, it
65576557
// can't be a library call. Don't do the check if marked as nobuiltin for
6558-
// some reason.
6558+
// some reason or the call site requires strict floating point semantics.
65596559
LibFunc Func;
6560-
if (!I.isNoBuiltin() && !F->hasLocalLinkage() && F->hasName() &&
6561-
LibInfo->getLibFunc(*F, Func) &&
6560+
if (!I.isNoBuiltin() && !I.isStrictFP() && !F->hasLocalLinkage() &&
6561+
F->hasName() && LibInfo->getLibFunc(*F, Func) &&
65626562
LibInfo->hasOptimizedCodeGen(Func)) {
65636563
switch (Func) {
65646564
default: break;

‎llvm/lib/IR/Attributes.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
327327
return "sspstrong";
328328
if (hasAttribute(Attribute::SafeStack))
329329
return "safestack";
330+
if (hasAttribute(Attribute::StrictFP))
331+
return "strictfp";
330332
if (hasAttribute(Attribute::StructRet))
331333
return "sret";
332334
if (hasAttribute(Attribute::SanitizeThread))

‎llvm/lib/IR/Verifier.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
13771377
case Attribute::InaccessibleMemOrArgMemOnly:
13781378
case Attribute::AllocSize:
13791379
case Attribute::Speculatable:
1380+
case Attribute::StrictFP:
13801381
return true;
13811382
default:
13821383
break;

‎llvm/lib/Transforms/IPO/ForceFunctionAttrs.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ static Attribute::AttrKind parseAttrKind(StringRef Kind) {
5757
.Case("ssp", Attribute::StackProtect)
5858
.Case("sspreq", Attribute::StackProtectReq)
5959
.Case("sspstrong", Attribute::StackProtectStrong)
60+
.Case("strictfp", Attribute::StrictFP)
6061
.Case("uwtable", Attribute::UWTable)
6162
.Default(Attribute::None);
6263
}

0 commit comments

Comments
 (0)
Please sign in to comment.