Skip to content

Commit 85d2b10

Browse files
authored
[DAG] Make strictfp attribute only restricts for libm and make non-math optimizations possible (#165464)
the patch [Add strictfp attribute to prevent unwanted optimizations of libm calls](https://reviews.llvm.org/D34163) add `I.isStrictFP()` into ``` if (!I.isNoBuiltin() && !I.isStrictFP() && !F->hasLocalLinkage() && F->hasName() && LibInfo->getLibFunc(*F, Func) && LibInfo->hasOptimizedCodeGen(Func)) ``` it prevents the backend from optimizing even non-math libcalls such as `strlen` and `memcmp` if a call has the strict floating-point attribute. For example, it prevent converting strlen and memcmp to milicode call __strlen and __memcmp.
1 parent 49dc49e commit 85d2b10

File tree

2 files changed

+43
-6
lines changed

2 files changed

+43
-6
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9456,7 +9456,9 @@ bool SelectionDAGBuilder::visitStrNLenCall(const CallInst &I) {
94569456
bool SelectionDAGBuilder::visitUnaryFloatCall(const CallInst &I,
94579457
unsigned Opcode) {
94589458
// We already checked this call's prototype; verify it doesn't modify errno.
9459-
if (!I.onlyReadsMemory())
9459+
// Do not perform optimizations for call sites that require strict
9460+
// floating-point semantics.
9461+
if (!I.onlyReadsMemory() || I.isStrictFP())
94609462
return false;
94619463

94629464
SDNodeFlags Flags;
@@ -9476,7 +9478,9 @@ bool SelectionDAGBuilder::visitUnaryFloatCall(const CallInst &I,
94769478
bool SelectionDAGBuilder::visitBinaryFloatCall(const CallInst &I,
94779479
unsigned Opcode) {
94789480
// We already checked this call's prototype; verify it doesn't modify errno.
9479-
if (!I.onlyReadsMemory())
9481+
// Do not perform optimizations for call sites that require strict
9482+
// floating-point semantics.
9483+
if (!I.onlyReadsMemory() || I.isStrictFP())
94809484
return false;
94819485

94829486
SDNodeFlags Flags;
@@ -9509,11 +9513,10 @@ void SelectionDAGBuilder::visitCall(const CallInst &I) {
95099513

95109514
// Check for well-known libc/libm calls. If the function is internal, it
95119515
// can't be a library call. Don't do the check if marked as nobuiltin for
9512-
// some reason or the call site requires strict floating point semantics.
9516+
// some reason.
95139517
LibFunc Func;
9514-
if (!I.isNoBuiltin() && !I.isStrictFP() && !F->hasLocalLinkage() &&
9515-
F->hasName() && LibInfo->getLibFunc(*F, Func) &&
9516-
LibInfo->hasOptimizedCodeGen(Func)) {
9518+
if (!I.isNoBuiltin() && !F->hasLocalLinkage() && F->hasName() &&
9519+
LibInfo->getLibFunc(*F, Func) && LibInfo->hasOptimizedCodeGen(Func)) {
95179520
switch (Func) {
95189521
default: break;
95199522
case LibFunc_bcmp:

llvm/test/CodeGen/PowerPC/milicode32.ll

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,41 @@ entry:
6868
ret i32 %call
6969
}
7070

71+
define i32 @strlen_test_fp_strict(ptr noundef %str) nounwind {
72+
; CHECK-AIX-32-P9-LABEL: strlen_test_fp_strict:
73+
; CHECK-AIX-32-P9: # %bb.0: # %entry
74+
; CHECK-AIX-32-P9-NEXT: mflr r0
75+
; CHECK-AIX-32-P9-NEXT: stwu r1, -64(r1)
76+
; CHECK-AIX-32-P9-NEXT: stw r0, 72(r1)
77+
; CHECK-AIX-32-P9-NEXT: stw r3, 60(r1)
78+
; CHECK-AIX-32-P9-NEXT: bl .___strlen[PR]
79+
; CHECK-AIX-32-P9-NEXT: nop
80+
; CHECK-AIX-32-P9-NEXT: addi r1, r1, 64
81+
; CHECK-AIX-32-P9-NEXT: lwz r0, 8(r1)
82+
; CHECK-AIX-32-P9-NEXT: mtlr r0
83+
; CHECK-AIX-32-P9-NEXT: blr
84+
;
85+
; CHECK-LINUX32-P9-LABEL: strlen_test_fp_strict:
86+
; CHECK-LINUX32-P9: # %bb.0: # %entry
87+
; CHECK-LINUX32-P9-NEXT: mflr r0
88+
; CHECK-LINUX32-P9-NEXT: stwu r1, -16(r1)
89+
; CHECK-LINUX32-P9-NEXT: stw r0, 20(r1)
90+
; CHECK-LINUX32-P9-NEXT: stw r3, 12(r1)
91+
; CHECK-LINUX32-P9-NEXT: bl strlen
92+
; CHECK-LINUX32-P9-NEXT: lwz r0, 20(r1)
93+
; CHECK-LINUX32-P9-NEXT: addi r1, r1, 16
94+
; CHECK-LINUX32-P9-NEXT: mtlr r0
95+
; CHECK-LINUX32-P9-NEXT: blr
96+
entry:
97+
%str.addr = alloca ptr, align 4
98+
store ptr %str, ptr %str.addr, align 4
99+
%0 = load ptr, ptr %str.addr, align 4
100+
%call = call i32 @strlen(ptr noundef %0) #0
101+
ret i32 %call
102+
}
103+
71104
declare i32 @strlen(ptr noundef) nounwind
105+
attributes #0 = { strictfp }
72106

73107
define ptr @test_memmove(ptr noundef %destination, ptr noundef %source, i32 noundef %num) #0 {
74108
; CHECK-AIX-32-P9-LABEL: test_memmove:

0 commit comments

Comments
 (0)