Skip to content

Commit ab17514

Browse files
committed
Also disable folding of operations with certain FMF flags
1 parent 941fbc7 commit ab17514

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

llvm/lib/Analysis/ConstantFolding.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,15 @@ Constant *llvm::ConstantFoldFPInstOperands(unsigned Opcode, Constant *LHS,
13731373
if (!Op1)
13741374
return nullptr;
13751375

1376+
// If nsz or an algebraic FMF flag is set, the result of the FP operation
1377+
// may change due to future optimization. Don't constant fold them if
1378+
// non-deterministic results are not allowed.
1379+
if (!AllowNonDeterministic)
1380+
if (auto *FP = dyn_cast_or_null<FPMathOperator>(I))
1381+
if (FP->hasNoSignedZeros() || FP->hasAllowReassoc() ||
1382+
FP->hasAllowContract() || FP->hasAllowReciprocal())
1383+
return nullptr;
1384+
13761385
// Calculate constant result.
13771386
Constant *C = ConstantFoldBinaryOpOperands(Opcode, Op0, Op1, DL);
13781387
if (!C)

llvm/test/Analysis/ScalarEvolution/exhaustive-trip-counts.ll

+97
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,103 @@ exit:
8080
ret i64 %iv
8181
}
8282

83+
; Do not compute exhaustive trip count based on FP constant folding if the
84+
; involved operation has nsz or one of the algebraic FMF flags (reassoc, arcp,
85+
; contract) set. The examples in the following are dummies and don't illustrate
86+
; real cases where FMF transforms could cause issues.
87+
88+
define i64 @test_fp_nsz() {
89+
; CHECK-LABEL: 'test_fp_nsz'
90+
; CHECK-NEXT: Determining loop execution counts for: @test_fp_nsz
91+
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
92+
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
93+
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
94+
;
95+
entry:
96+
br label %loop
97+
98+
loop:
99+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
100+
%fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
101+
call void @use(double %fv)
102+
%fv.next = fadd nsz double %fv, 1.0
103+
%iv.next = add i64 %iv, 1
104+
%fcmp = fcmp une double %fv, 100.0
105+
br i1 %fcmp, label %loop, label %exit
106+
107+
exit:
108+
ret i64 %iv
109+
}
110+
111+
define i64 @test_fp_reassoc() {
112+
; CHECK-LABEL: 'test_fp_reassoc'
113+
; CHECK-NEXT: Determining loop execution counts for: @test_fp_reassoc
114+
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
115+
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
116+
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
117+
;
118+
entry:
119+
br label %loop
120+
121+
loop:
122+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
123+
%fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
124+
call void @use(double %fv)
125+
%fv.next = fadd reassoc double %fv, 1.0
126+
%iv.next = add i64 %iv, 1
127+
%fcmp = fcmp une double %fv, 100.0
128+
br i1 %fcmp, label %loop, label %exit
129+
130+
exit:
131+
ret i64 %iv
132+
}
133+
134+
define i64 @test_fp_arcp() {
135+
; CHECK-LABEL: 'test_fp_arcp'
136+
; CHECK-NEXT: Determining loop execution counts for: @test_fp_arcp
137+
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
138+
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
139+
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
140+
;
141+
entry:
142+
br label %loop
143+
144+
loop:
145+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
146+
%fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
147+
call void @use(double %fv)
148+
%fv.next = fadd arcp double %fv, 1.0
149+
%iv.next = add i64 %iv, 1
150+
%fcmp = fcmp une double %fv, 100.0
151+
br i1 %fcmp, label %loop, label %exit
152+
153+
exit:
154+
ret i64 %iv
155+
}
156+
157+
define i64 @test_fp_contract() {
158+
; CHECK-LABEL: 'test_fp_contract'
159+
; CHECK-NEXT: Determining loop execution counts for: @test_fp_contract
160+
; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count.
161+
; CHECK-NEXT: Loop %loop: Unpredictable constant max backedge-taken count.
162+
; CHECK-NEXT: Loop %loop: Unpredictable symbolic max backedge-taken count.
163+
;
164+
entry:
165+
br label %loop
166+
167+
loop:
168+
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
169+
%fv = phi double [ 1.000000e+00, %entry ], [ %fv.next, %loop ]
170+
call void @use(double %fv)
171+
%fv.next = fadd contract double %fv, 1.0
172+
%iv.next = add i64 %iv, 1
173+
%fcmp = fcmp une double %fv, 100.0
174+
br i1 %fcmp, label %loop, label %exit
175+
176+
exit:
177+
ret i64 %iv
178+
}
179+
83180
declare void @dummy()
84181
declare void @use(double %i)
85182
declare double @llvm.sin.f64(double)

0 commit comments

Comments
 (0)