llvm.org GIT mirror llvm / 68d0bd1
Add strictfp attribute to prevent unwanted optimizations of libm calls Differential Revision: https://reviews.llvm.org/D34163 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310885 91177308-0d34-0410-b5e6-96231b3b80d8 Andrew Kaylor 2 years ago
22 changed file(s) with 172 addition(s) and 83 deletion(s). Raw diff Collapse all Expand all
16431643 If a function that has an ``sspstrong`` attribute is inlined into a
16441644 function that doesn't have an ``sspstrong`` attribute, then the
16451645 resulting function will have an ``sspstrong`` attribute.
1646 ``strictfp``
1647 This attribute indicates that the function was called from a scope that
1648 requires strict floating point semantics. LLVM will not attempt any
1649 optimizations that require assumptions about the floating point rounding
1650 mode or that might alter the state of floating point status flags that
1651 might otherwise be set or cleared by calling this function.
16461652 ``"thunk"``
16471653 This attribute indicates that the function will delegate to some other
16481654 function with a tail call. The prototype of a thunk should not be used for
557557 ATTR_KIND_INACCESSIBLEMEM_OR_ARGMEMONLY = 50,
558558 ATTR_KIND_ALLOC_SIZE = 51,
559559 ATTR_KIND_WRITEONLY = 52,
560 ATTR_KIND_SPECULATABLE = 53
560 ATTR_KIND_SPECULATABLE = 53,
561 ATTR_KIND_STRICT_FP = 54,
561562 };
562563
563564 enum ComdatSelectionKindCodes {
147147
148148 /// Strong Stack protection.
149149 def StackProtectStrong : EnumAttr<"sspstrong">;
150
151 /// Function was called in a scope requiring strict floating point semantics.
152 def StrictFP : EnumAttr<"strictfp">;
150153
151154 /// Hidden pointer to structure to return.
152155 def StructRet : EnumAttr<"sret">;
425425 CALLSITE_DELEGATE_GETTER(isNoBuiltin());
426426 }
427427
428 /// Return true if the call requires strict floating point semantics.
429 bool isStrictFP() const {
430 CALLSITE_DELEGATE_GETTER(isStrictFP());
431 }
432
428433 /// Return true if the call should not be inlined.
429434 bool isNoInline() const {
430435 CALLSITE_DELEGATE_GETTER(isNoInline());
17561756 !hasFnAttrImpl(Attribute::Builtin);
17571757 }
17581758
1759 /// Determine if the call requires strict floating point semantics.
1760 bool isStrictFP() const { return hasFnAttr(Attribute::StrictFP); }
1761
17591762 /// Return true if the call should not be inlined.
17601763 bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
17611764 void setIsNoInline() {
38433846 !hasFnAttrImpl(Attribute::Builtin);
38443847 }
38453848
3849 /// Determine if the call requires strict floating point semantics.
3850 bool isStrictFP() const { return hasFnAttr(Attribute::StrictFP); }
3851
38463852 /// Return true if the call should not be inlined.
38473853 bool isNoInline() const { return hasFnAttr(Attribute::NoInline); }
38483854 void setIsNoInline() {
136136 Value *optimizeSqrt(CallInst *CI, IRBuilder<> &B);
137137 Value *optimizeSinCosPi(CallInst *CI, IRBuilder<> &B);
138138 Value *optimizeTan(CallInst *CI, IRBuilder<> &B);
139 // Wrapper for all floating point library call optimizations
140 Value *optimizeFloatingPointLibCall(CallInst *CI, LibFunc Func,
141 IRBuilder<> &B);
139142
140143 // Integer Library Call Optimizations
141144 Value *optimizeFFS(CallInst *CI, IRBuilder<> &B);
13581358 //
13591359
13601360 bool llvm::canConstantFoldCallTo(ImmutableCallSite CS, const Function *F) {
1361 if (CS.isNoBuiltin())
1361 if (CS.isNoBuiltin() || CS.isStrictFP())
13621362 return false;
13631363 switch (F->getIntrinsicID()) {
13641364 case Intrinsic::fabs:
20652065 llvm::ConstantFoldCall(ImmutableCallSite CS, Function *F,
20662066 ArrayRef Operands,
20672067 const TargetLibraryInfo *TLI) {
2068 if (CS.isNoBuiltin())
2068 if (CS.isNoBuiltin() || CS.isStrictFP())
20692069 return nullptr;
20702070 if (!F->hasName())
20712071 return nullptr;
20832083 bool llvm::isMathLibCallNoop(CallSite CS, const TargetLibraryInfo *TLI) {
20842084 // FIXME: Refactor this code; this duplicates logic in LibCallsShrinkWrap
20852085 // (and to some extent ConstantFoldScalarCall).
2086 if (CS.isNoBuiltin())
2086 if (CS.isNoBuiltin() || CS.isStrictFP())
20872087 return false;
20882088 Function *F = CS.getCalledFunction();
20892089 if (!F)
653653 KEYWORD(ssp);
654654 KEYWORD(sspreq);
655655 KEYWORD(sspstrong);
656 KEYWORD(strictfp);
656657 KEYWORD(safestack);
657658 KEYWORD(sanitize_address);
658659 KEYWORD(sanitize_thread);
11201120 B.addAttribute(Attribute::SanitizeThread); break;
11211121 case lltok::kw_sanitize_memory:
11221122 B.addAttribute(Attribute::SanitizeMemory); break;
1123 case lltok::kw_strictfp: B.addAttribute(Attribute::StrictFP); break;
11231124 case lltok::kw_uwtable: B.addAttribute(Attribute::UWTable); break;
11241125 case lltok::kw_writeonly: B.addAttribute(Attribute::WriteOnly); break;
11251126
14451446 case lltok::kw_sspreq:
14461447 case lltok::kw_sspstrong:
14471448 case lltok::kw_safestack:
1449 case lltok::kw_strictfp:
14481450 case lltok::kw_uwtable:
14491451 HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
14501452 break;
15361538 case lltok::kw_sspreq:
15371539 case lltok::kw_sspstrong:
15381540 case lltok::kw_safestack:
1541 case lltok::kw_strictfp:
15391542 case lltok::kw_uwtable:
15401543 HaveError |= Error(Lex.getLoc(), "invalid use of function-only attribute");
15411544 break;
206206 kw_sret,
207207 kw_sanitize_thread,
208208 kw_sanitize_memory,
209 kw_strictfp,
209210 kw_swifterror,
210211 kw_swiftself,
211212 kw_uwtable,
11361136 case Attribute::SwiftError: return 1ULL << 52;
11371137 case Attribute::WriteOnly: return 1ULL << 53;
11381138 case Attribute::Speculatable: return 1ULL << 54;
1139 case Attribute::StrictFP: return 1ULL << 55;
11391140 case Attribute::Dereferenceable:
11401141 llvm_unreachable("dereferenceable attribute not supported in raw format");
11411142 break;
13441345 return Attribute::StackProtectStrong;
13451346 case bitc::ATTR_KIND_SAFESTACK:
13461347 return Attribute::SafeStack;
1348 case bitc::ATTR_KIND_STRICT_FP:
1349 return Attribute::StrictFP;
13471350 case bitc::ATTR_KIND_STRUCT_RET:
13481351 return Attribute::StructRet;
13491352 case bitc::ATTR_KIND_SANITIZE_ADDRESS:
609609 return bitc::ATTR_KIND_STACK_PROTECT_STRONG;
610610 case Attribute::SafeStack:
611611 return bitc::ATTR_KIND_SAFESTACK;
612 case Attribute::StrictFP:
613 return bitc::ATTR_KIND_STRICT_FP;
612614 case Attribute::StructRet:
613615 return bitc::ATTR_KIND_STRUCT_RET;
614616 case Attribute::SanitizeAddress:
65546554
65556555 // Check for well-known libc/libm calls. If the function is internal, it
65566556 // can't be a library call. Don't do the check if marked as nobuiltin for
6557 // some reason.
6557 // some reason or the call site requires strict floating point semantics.
65586558 LibFunc Func;
6559 if (!I.isNoBuiltin() && !F->hasLocalLinkage() && F->hasName() &&
6560 LibInfo->getLibFunc(*F, Func) &&
6559 if (!I.isNoBuiltin() && !I.isStrictFP() && !F->hasLocalLinkage() &&
6560 F->hasName() && LibInfo->getLibFunc(*F, Func) &&
65616561 LibInfo->hasOptimizedCodeGen(Func)) {
65626562 switch (Func) {
65636563 default: break;
326326 return "sspstrong";
327327 if (hasAttribute(Attribute::SafeStack))
328328 return "safestack";
329 if (hasAttribute(Attribute::StrictFP))
330 return "strictfp";
329331 if (hasAttribute(Attribute::StructRet))
330332 return "sret";
331333 if (hasAttribute(Attribute::SanitizeThread))
13761376 case Attribute::InaccessibleMemOrArgMemOnly:
13771377 case Attribute::AllocSize:
13781378 case Attribute::Speculatable:
1379 case Attribute::StrictFP:
13791380 return true;
13801381 default:
13811382 break;
5656 .Case("ssp", Attribute::StackProtect)
5757 .Case("sspreq", Attribute::StackProtectReq)
5858 .Case("sspstrong", Attribute::StackProtectStrong)
59 .Case("strictfp", Attribute::StrictFP)
5960 .Case("uwtable", Attribute::UWTable)
6061 .Default(Attribute::None);
6162 }
20402040 return nullptr;
20412041 }
20422042
2043 Value *LibCallSimplifier::optimizeFloatingPointLibCall(CallInst *CI,
2044 LibFunc Func,
2045 IRBuilder<> &Builder) {
2046 // Don't optimize calls that require strict floating point semantics.
2047 if (CI->isStrictFP())
2048 return nullptr;
2049
2050 switch (Func) {
2051 case LibFunc_cosf:
2052 case LibFunc_cos:
2053 case LibFunc_cosl:
2054 return optimizeCos(CI, Builder);
2055 case LibFunc_sinpif:
2056 case LibFunc_sinpi:
2057 case LibFunc_cospif:
2058 case LibFunc_cospi:
2059 return optimizeSinCosPi(CI, Builder);
2060 case LibFunc_powf:
2061 case LibFunc_pow:
2062 case LibFunc_powl:
2063 return optimizePow(CI, Builder);
2064 case LibFunc_exp2l:
2065 case LibFunc_exp2:
2066 case LibFunc_exp2f:
2067 return optimizeExp2(CI, Builder);
2068 case LibFunc_fabsf:
2069 case LibFunc_fabs:
2070 case LibFunc_fabsl:
2071 return replaceUnaryCall(CI, Builder, Intrinsic::fabs);
2072 case LibFunc_sqrtf:
2073 case LibFunc_sqrt:
2074 case LibFunc_sqrtl:
2075 return optimizeSqrt(CI, Builder);
2076 case LibFunc_log:
2077 case LibFunc_log10:
2078 case LibFunc_log1p:
2079 case LibFunc_log2:
2080 case LibFunc_logb:
2081 return optimizeLog(CI, Builder);
2082 case LibFunc_tan:
2083 case LibFunc_tanf:
2084 case LibFunc_tanl:
2085 return optimizeTan(CI, Builder);
2086 case LibFunc_ceil:
2087 return replaceUnaryCall(CI, Builder, Intrinsic::ceil);
2088 case LibFunc_floor:
2089 return replaceUnaryCall(CI, Builder, Intrinsic::floor);
2090 case LibFunc_round:
2091 return replaceUnaryCall(CI, Builder, Intrinsic::round);
2092 case LibFunc_nearbyint:
2093 return replaceUnaryCall(CI, Builder, Intrinsic::nearbyint);
2094 case LibFunc_rint:
2095 return replaceUnaryCall(CI, Builder, Intrinsic::rint);
2096 case LibFunc_trunc:
2097 return replaceUnaryCall(CI, Builder, Intrinsic::trunc);
2098 case LibFunc_acos:
2099 case LibFunc_acosh:
2100 case LibFunc_asin:
2101 case LibFunc_asinh:
2102 case LibFunc_atan:
2103 case LibFunc_atanh:
2104 case LibFunc_cbrt:
2105 case LibFunc_cosh:
2106 case LibFunc_exp:
2107 case LibFunc_exp10:
2108 case LibFunc_expm1:
2109 case LibFunc_sin:
2110 case LibFunc_sinh:
2111 case LibFunc_tanh:
2112 if (UnsafeFPShrink && hasFloatVersion(CI->getCalledFunction()->getName()))
2113 return optimizeUnaryDoubleFP(CI, Builder, true);
2114 return nullptr;
2115 case LibFunc_copysign:
2116 if (hasFloatVersion(CI->getCalledFunction()->getName()))
2117 return optimizeBinaryDoubleFP(CI, Builder);
2118 return nullptr;
2119 case LibFunc_fminf:
2120 case LibFunc_fmin:
2121 case LibFunc_fminl:
2122 case LibFunc_fmaxf:
2123 case LibFunc_fmax:
2124 case LibFunc_fmaxl:
2125 return optimizeFMinFMax(CI, Builder);
2126 default:
2127 return nullptr;
2128 }
2129 }
2130
20432131 Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
2132 // TODO: Split out the code below that operates on FP calls so that
2133 // we can all non-FP calls with the StrictFP attribute to be
2134 // optimized.
20442135 if (CI->isNoBuiltin())
20452136 return nullptr;
20462137
20472138 LibFunc Func;
20482139 Function *Callee = CI->getCalledFunction();
2049 StringRef FuncName = Callee->getName();
20502140
20512141 SmallVector OpBundles;
20522142 CI->getOperandBundlesAsDefs(OpBundles);
20542144 bool isCallingConvC = isCallingConvCCompatible(CI);
20552145
20562146 // Command-line parameter overrides instruction attribute.
2147 // This can't be moved to optimizeFloatingPointLibCall() because it may be
2148 // used by the intrinsic optimizations.
20572149 if (EnableUnsafeFPShrink.getNumOccurrences() > 0)
20582150 UnsafeFPShrink = EnableUnsafeFPShrink;
20592151 else if (isa(CI) && CI->hasUnsafeAlgebra())
20632155 if (IntrinsicInst *II = dyn_cast(CI)) {
20642156 if (!isCallingConvC)
20652157 return nullptr;
2158 // The FP intrinsics have corresponding constrained versions so we don't
2159 // need to check for the StrictFP attribute here.
20662160 switch (II->getIntrinsicID()) {
20672161 case Intrinsic::pow:
20682162 return optimizePow(CI, Builder);
21032197 return nullptr;
21042198 if (Value *V = optimizeStringMemoryLibCall(CI, Builder))
21052199 return V;
2200 if (Value *V = optimizeFloatingPointLibCall(CI, Func, Builder))
2201 return V;
21062202 switch (Func) {
2107 case LibFunc_cosf:
2108 case LibFunc_cos:
2109 case LibFunc_cosl:
2110 return optimizeCos(CI, Builder);
2111 case LibFunc_sinpif:
2112 case LibFunc_sinpi:
2113 case LibFunc_cospif:
2114 case LibFunc_cospi:
2115 return optimizeSinCosPi(CI, Builder);
2116 case LibFunc_powf:
2117 case LibFunc_pow:
2118 case LibFunc_powl:
2119 return optimizePow(CI, Builder);
2120 case LibFunc_exp2l:
2121 case LibFunc_exp2:
2122 case LibFunc_exp2f:
2123 return optimizeExp2(CI, Builder);
2124 case LibFunc_fabsf:
2125 case LibFunc_fabs:
2126 case LibFunc_fabsl:
2127 return replaceUnaryCall(CI, Builder, Intrinsic::fabs);
2128 case LibFunc_sqrtf:
2129 case LibFunc_sqrt:
2130 case LibFunc_sqrtl:
2131 return optimizeSqrt(CI, Builder);
21322203 case LibFunc_ffs:
21332204 case LibFunc_ffsl:
21342205 case LibFunc_ffsll:
21572228 return optimizeFWrite(CI, Builder);
21582229 case LibFunc_fputs:
21592230 return optimizeFPuts(CI, Builder);
2160 case LibFunc_log:
2161 case LibFunc_log10:
2162 case LibFunc_log1p:
2163 case LibFunc_log2:
2164 case LibFunc_logb:
2165 return optimizeLog(CI, Builder);
21662231 case LibFunc_puts:
21672232 return optimizePuts(CI, Builder);
2168 case LibFunc_tan:
2169 case LibFunc_tanf:
2170 case LibFunc_tanl:
2171 return optimizeTan(CI, Builder);
21722233 case LibFunc_perror:
21732234 return optimizeErrorReporting(CI, Builder);
21742235 case LibFunc_vfprintf:
21762237 return optimizeErrorReporting(CI, Builder, 0);
21772238 case LibFunc_fputc:
21782239 return optimizeErrorReporting(CI, Builder, 1);
2179 case LibFunc_ceil:
2180 return replaceUnaryCall(CI, Builder, Intrinsic::ceil);
2181 case LibFunc_floor:
2182 return replaceUnaryCall(CI, Builder, Intrinsic::floor);
2183 case LibFunc_round:
2184 return replaceUnaryCall(CI, Builder, Intrinsic::round);
2185 case LibFunc_nearbyint:
2186 return replaceUnaryCall(CI, Builder, Intrinsic::nearbyint);
2187 case LibFunc_rint:
2188 return replaceUnaryCall(CI, Builder, Intrinsic::rint);
2189 case LibFunc_trunc:
2190 return replaceUnaryCall(CI, Builder, Intrinsic::trunc);
2191 case LibFunc_acos:
2192 case LibFunc_acosh:
2193 case LibFunc_asin:
2194 case LibFunc_asinh:
2195 case LibFunc_atan:
2196 case LibFunc_atanh:
2197 case LibFunc_cbrt:
2198 case LibFunc_cosh:
2199 case LibFunc_exp:
2200 case LibFunc_exp10:
2201 case LibFunc_expm1:
2202 case LibFunc_sin:
2203 case LibFunc_sinh:
2204 case LibFunc_tanh:
2205 if (UnsafeFPShrink && hasFloatVersion(FuncName))
2206 return optimizeUnaryDoubleFP(CI, Builder, true);
2207 return nullptr;
2208 case LibFunc_copysign:
2209 if (hasFloatVersion(FuncName))
2210 return optimizeBinaryDoubleFP(CI, Builder);
2211 return nullptr;
2212 case LibFunc_fminf:
2213 case LibFunc_fmin:
2214 case LibFunc_fminl:
2215 case LibFunc_fmaxf:
2216 case LibFunc_fmax:
2217 case LibFunc_fmaxl:
2218 return optimizeFMinFMax(CI, Builder);
22192240 default:
22202241 return nullptr;
22212242 }
607607 ; CHECK: declare void @f.inaccessiblememonly() #33
608608 declare void @f.inaccessiblemem_or_argmemonly() inaccessiblemem_or_argmemonly
609609 ; CHECK: declare void @f.inaccessiblemem_or_argmemonly() #34
610 declare void @f.strictfp() #35
610611
611612 ; Functions -- section
612613 declare void @f.section() section "80"
12511252 call void @f.nobuiltin() builtin
12521253 ; CHECK: call void @f.nobuiltin() #42
12531254
1255 call void @f.strictfp() strictfp
1256 ; CHECK: call void @f.strictfp() #43
1257
12541258 call fastcc noalias i32* @f.noalias() noinline
12551259 ; CHECK: call fastcc noalias i32* @f.noalias() #12
12561260 tail call ghccc nonnull i32* @f.nonnull() minsize
16691673 ; CHECK: attributes #40 = { writeonly }
16701674 ; CHECK: attributes #41 = { speculatable }
16711675 ; CHECK: attributes #42 = { builtin }
1676 ; CHECK: attributes #43 = { strictfp }
16721677
16731678 ;; Metadata
16741679
7575 ; CHECK-NEXT: %cos3 = call double @cos(double 0.000000e+00)
7676 %cos3 = call double @cos(double 0.000000e+00) nobuiltin
7777
78 ; cos(1) strictfp sets FP status flags
79 ; CHECK-NEXT: %cos4 = call double @cos(double 1.000000e+00)
80 %cos4 = call double @cos(double 1.000000e+00) strictfp
81
7882 ; pow(0, 1) is 0
7983 %pow1 = call double @pow(double 0x7FF0000000000000, double 1.000000e+00)
8084
1111 ret double %pi
1212 }
1313
14 ; Check that we don't constant fold builtin functions.
15
1416 define double @test_acos_nobuiltin() {
1517 ; CHECK-LABEL: @test_acos_nobuiltin
1618 %pi = call double @acos(double -1.000000e+00) nobuiltin
1719 ; CHECK: call double @acos(double -1.000000e+00)
1820 ret double %pi
1921 }
22
23 ; Check that we don't constant fold strictfp results that require rounding.
24
25 define double @test_acos_strictfp() {
26 ; CHECK-LABEL: @test_acos_strictfp
27 %pi = call double @acos(double -1.000000e+00) strictfp
28 ; CHECK: call double @acos(double -1.000000e+00)
29 ret double %pi
30 }
1616 ret i8* %ret
1717 }
1818
19 ; Verify that the strictfp attr doesn't block this optimization.
20
21 define i8* @test_simplify2(i8* %mem1, i8* %mem2, i32 %size) {
22 ; CHECK-LABEL: @test_simplify2(
23 %ret = call i8* @memcpy(i8* %mem1, i8* %mem2, i32 %size) strictfp
24 ; CHECK: call void @llvm.memcpy
25 ret i8* %ret
26 ; CHECK: ret i8* %mem1
27 }
143143 \ ssp
144144 \ sspreq
145145 \ sspstrong
146 \ strictfp
146147 \ swiftcc
147148 \ tail
148149 \ target