Skip to content

Commit a870604

Browse files
[InferAttrs] Mark floating-point libcalls as errno-writing
Floating-point libcalls are currently conservatively marked as may write any memory. Restrict these to clobber only `errno`.
1 parent 029bece commit a870604

File tree

5 files changed

+200
-177
lines changed

5 files changed

+200
-177
lines changed

llvm/include/llvm/IR/Function.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
571571
bool onlyWritesMemory() const;
572572
void setOnlyWritesMemory();
573573

574-
/// Determine if the call can access memmory only using pointers based
574+
/// Determine if the call can access memory only using pointers based
575575
/// on its arguments.
576576
bool onlyAccessesArgMemory() const;
577577
void setOnlyAccessesArgMemory();
@@ -581,6 +581,10 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
581581
bool onlyAccessesInaccessibleMemory() const;
582582
void setOnlyAccessesInaccessibleMemory();
583583

584+
/// Determine if the call can access only errno memory.
585+
bool onlyAccessesErrnoMemory() const;
586+
void setOnlyAccessesErrnoMemory();
587+
584588
/// Determine if the function may only access memory that is
585589
/// either inaccessible from the IR or pointed to by its arguments.
586590
bool onlyAccessesInaccessibleMemOrArgMem() const;

llvm/lib/IR/Function.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ void Function::setOnlyWritesMemory() {
904904
setMemoryEffects(getMemoryEffects() & MemoryEffects::writeOnly());
905905
}
906906

907-
/// Determine if the call can access memmory only using pointers based
907+
/// Determine if the call can access memory only using pointers based
908908
/// on its arguments.
909909
bool Function::onlyAccessesArgMemory() const {
910910
return getMemoryEffects().onlyAccessesArgPointees();
@@ -922,6 +922,14 @@ void Function::setOnlyAccessesInaccessibleMemory() {
922922
setMemoryEffects(getMemoryEffects() & MemoryEffects::inaccessibleMemOnly());
923923
}
924924

925+
/// Determine if the call can access only errno memory.
926+
bool Function::onlyAccessesErrnoMemory() const {
927+
return getMemoryEffects().onlyAccessesErrnoMem();
928+
}
929+
void Function::setOnlyAccessesErrnoMemory() {
930+
setMemoryEffects(getMemoryEffects() & MemoryEffects::errnoMemOnly());
931+
}
932+
925933
/// Determine if the function may only access memory that is
926934
/// either inaccessible from the IR or pointed to by its arguments.
927935
bool Function::onlyAccessesInaccessibleMemOrArgMem() const {

llvm/lib/Transforms/Utils/BuildLibCalls.cpp

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ STATISTIC(NumInaccessibleMemOnly,
3939
STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
4040
STATISTIC(NumWriteOnly, "Number of functions inferred as writeonly");
4141
STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
42+
STATISTIC(NumErrnoMemOnly, "Number of functions inferred as errnomemonly");
4243
STATISTIC(NumInaccessibleMemOrArgMemOnly,
4344
"Number of functions inferred as inaccessiblemem_or_argmemonly");
4445
STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
@@ -84,6 +85,14 @@ static bool setOnlyAccessesInaccessibleMemory(Function &F) {
8485
return true;
8586
}
8687

88+
static bool setOnlyAccessesErrnoMemory(Function &F) {
89+
if (F.onlyAccessesErrnoMemory())
90+
return false;
91+
F.setOnlyAccessesErrnoMemory();
92+
++NumErrnoMemOnly;
93+
return true;
94+
}
95+
8796
static bool setOnlyReadsMemory(Function &F) {
8897
if (F.onlyReadsMemory())
8998
return false;
@@ -1145,14 +1154,14 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
11451154
case LibFunc_ldexp:
11461155
case LibFunc_ldexpf:
11471156
case LibFunc_ldexpl:
1157+
Changed |= setOnlyAccessesErrnoMemory(F);
11481158
Changed |= setWillReturn(F);
11491159
break;
11501160
case LibFunc_remquo:
11511161
case LibFunc_remquof:
11521162
case LibFunc_remquol:
11531163
Changed |= setDoesNotCapture(F, 2);
11541164
[[fallthrough]];
1155-
case LibFunc_abs:
11561165
case LibFunc_acos:
11571166
case LibFunc_acosf:
11581167
case LibFunc_acosh:
@@ -1174,15 +1183,9 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
11741183
case LibFunc_atanhf:
11751184
case LibFunc_atanhl:
11761185
case LibFunc_atanl:
1177-
case LibFunc_cbrt:
1178-
case LibFunc_cbrtf:
1179-
case LibFunc_cbrtl:
11801186
case LibFunc_ceil:
11811187
case LibFunc_ceilf:
11821188
case LibFunc_ceill:
1183-
case LibFunc_copysign:
1184-
case LibFunc_copysignf:
1185-
case LibFunc_copysignl:
11861189
case LibFunc_cos:
11871190
case LibFunc_cosh:
11881191
case LibFunc_coshf:
@@ -1206,37 +1209,18 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
12061209
case LibFunc_expm1:
12071210
case LibFunc_expm1f:
12081211
case LibFunc_expm1l:
1209-
case LibFunc_fabs:
1210-
case LibFunc_fabsf:
1211-
case LibFunc_fabsl:
12121212
case LibFunc_fdim:
12131213
case LibFunc_fdiml:
12141214
case LibFunc_fdimf:
1215-
case LibFunc_ffs:
1216-
case LibFunc_ffsl:
1217-
case LibFunc_ffsll:
12181215
case LibFunc_floor:
12191216
case LibFunc_floorf:
12201217
case LibFunc_floorl:
1221-
case LibFunc_fls:
1222-
case LibFunc_flsl:
1223-
case LibFunc_flsll:
1224-
case LibFunc_fmax:
1225-
case LibFunc_fmaxf:
1226-
case LibFunc_fmaxl:
1227-
case LibFunc_fmin:
1228-
case LibFunc_fminf:
1229-
case LibFunc_fminl:
12301218
case LibFunc_fmod:
12311219
case LibFunc_fmodf:
12321220
case LibFunc_fmodl:
12331221
case LibFunc_hypot:
12341222
case LibFunc_hypotf:
12351223
case LibFunc_hypotl:
1236-
case LibFunc_isascii:
1237-
case LibFunc_isdigit:
1238-
case LibFunc_labs:
1239-
case LibFunc_llabs:
12401224
case LibFunc_log:
12411225
case LibFunc_log10:
12421226
case LibFunc_log10f:
@@ -1294,26 +1278,53 @@ bool llvm::inferNonMandatoryLibFuncAttrs(Function &F,
12941278
case LibFunc_tanhf:
12951279
case LibFunc_tanhl:
12961280
case LibFunc_tanl:
1281+
Changed |= setOnlyAccessesErrnoMemory(F);
1282+
[[fallthrough]];
1283+
case LibFunc_abs:
1284+
case LibFunc_cbrt:
1285+
case LibFunc_cbrtf:
1286+
case LibFunc_cbrtl:
1287+
case LibFunc_copysign:
1288+
case LibFunc_copysignf:
1289+
case LibFunc_copysignl:
1290+
case LibFunc_fabs:
1291+
case LibFunc_fabsf:
1292+
case LibFunc_fabsl:
1293+
case LibFunc_ffs:
1294+
case LibFunc_ffsl:
1295+
case LibFunc_ffsll:
1296+
case LibFunc_fls:
1297+
case LibFunc_flsl:
1298+
case LibFunc_flsll:
1299+
case LibFunc_fmax:
1300+
case LibFunc_fmaxf:
1301+
case LibFunc_fmaxl:
1302+
case LibFunc_fmin:
1303+
case LibFunc_fminf:
1304+
case LibFunc_fminl:
1305+
case LibFunc_isascii:
1306+
case LibFunc_isdigit:
1307+
case LibFunc_labs:
1308+
case LibFunc_llabs:
12971309
case LibFunc_toascii:
12981310
case LibFunc_trunc:
12991311
case LibFunc_truncf:
13001312
case LibFunc_truncl:
13011313
Changed |= setDoesNotThrow(F);
13021314
Changed |= setDoesNotFreeMemory(F);
1303-
Changed |= setOnlyWritesMemory(F);
13041315
Changed |= setWillReturn(F);
13051316
break;
13061317
case LibFunc_sincos:
13071318
case LibFunc_sincosf:
13081319
case LibFunc_sincosl:
13091320
Changed |= setDoesNotThrow(F);
13101321
Changed |= setDoesNotFreeMemory(F);
1311-
Changed |= setOnlyWritesMemory(F);
13121322
Changed |= setOnlyWritesMemory(F, 1);
13131323
Changed |= setOnlyWritesMemory(F, 2);
13141324
Changed |= setDoesNotCapture(F, 1);
13151325
Changed |= setDoesNotCapture(F, 2);
13161326
Changed |= setWillReturn(F);
1327+
Changed |= setOnlyAccessesErrnoMemory(F);
13171328
break;
13181329
default:
13191330
// FIXME: It'd be really nice to cover all the library functions we're

0 commit comments

Comments
 (0)