-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Reopen of Bug 49389 - Condition not constant folded #90417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
It seems using Nevertheless, I wonder which pass could be responsible of that kind of optimisation I looked at
but if we duplicate define dso_local i1 @eat_digits(ptr nocapture noundef readonly %s) local_unnamed_addr #0 {
entry:
br label %while.cond
while.cond: ; preds = %while.body, %entry
%i.0 = phi i64 [ 0, %entry ], [ %add, %while.body ]
%exitcond.not = icmp eq i64 %i.0, 1234
br i1 %exitcond.not, label %common.ret, label %while.body
while.body: ; preds = %while.cond
%arrayidx = getelementptr inbounds i8, ptr %s, i64 %i.0
%0 = load i8, ptr %arrayidx, align 1
%1 = add i8 %0, -48
%or.cond = icmp ult i8 %1, 10
%add = add nuw nsw i64 %i.0, 1
br i1 %or.cond, label %while.cond, label %while.end.2
common.ret: ; preds = %while.cond, %while.end.2
%common.ret.op = phi i1 [ %cmp7, %while.end.2 ], [ true, %while.cond ]
ret i1 %common.ret.op
while.end.2: ; preds = %while.body
%cmp7 = icmp ult i64 %i.0, 1235
br label %common.ret
}
llvm-project/llvm/lib/Transforms/Scalar/ConstraintElimination.cpp Lines 199 to 204 in 6f02120
|
@fhahn Do you think this bug is related to |
The faulty case manually fed to define dso_local i1 @eat_digits(ptr nocapture noundef readonly %s) local_unnamed_addr #0 {
entry:
br label %while.cond
while.cond: ; preds = %while.body, %entry
%i.0 = phi i64 [ 0, %entry ], [ %add, %while.body ]
%exitcond.not = icmp eq i64 %i.0, 1234
br i1 %exitcond.not, label %while.end, label %while.body
while.body: ; preds = %while.cond
%arrayidx = getelementptr inbounds i8, ptr %s, i64 %i.0
%0 = load i8, ptr %arrayidx, align 1
%1 = add i8 %0, -48
%or.cond = icmp ult i8 %1, 10
%add = add nuw nsw i64 %i.0, 1
; %add = add i64 %i.0, 1
br i1 %or.cond, label %while.cond, label %while.end
while.end: ; preds = %while.body, %while.cond
%cmp6 = icmp ult i64 %i.0, 1235
ret i1 %cmp6
} $ opt faulty_manual.ll -passes="print<scalar-evolution>"
Printing analysis 'Scalar Evolution Analysis' for function 'eat_digits':
Classifying expressions for: @eat_digits
%i.0 = phi i64 [ 0, %entry ], [ %add, %while.body ]
--> {0,+,1}<nuw><nsw><%while.cond> U: [0,1235) S: [0,1235) Exits: <<Unknown>> LoopDispositions: { %while.cond: Computable }
%arrayidx = getelementptr inbounds i8, ptr %s, i64 %i.0
--> {%s,+,1}<nw><%while.cond> U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond: Computable }
%0 = load i8, ptr %arrayidx, align 1
--> %0 U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond: Variant }
%1 = add i8 %0, -48
--> (-48 + %0) U: full-set S: full-set Exits: <<Unknown>> LoopDispositions: { %while.cond: Variant }
%add = add nuw nsw i64 %i.0, 1
--> {1,+,1}<nuw><nsw><%while.cond> U: [1,1236) S: [1,1236) Exits: <<Unknown>> LoopDispositions: { %while.cond: Computable }
Determining loop execution counts for: @eat_digits
Loop %while.cond: <multiple exits> Unpredictable backedge-taken count.
exit count for while.cond: i64 1234
exit count for while.body: ***COULDNOTCOMPUTE***
Loop %while.cond: constant max backedge-taken count is i64 1234
Loop %while.cond: symbolic max backedge-taken count is i64 1234
symbolic max exit count for while.cond: i64 1234
symbolic max exit count for while.body: ***COULDNOTCOMPUTE***
|
When looking at the loop counter, if the min/max values of the SCEV ranges are relevant (not extremal), add this information as ConditionFacts for the Loop header. It allows icmp simplifications independently of the branch taken, such as using `i <= N` after a block `for(i=0; i<N; i+=1) { ... }`. Fixes llvm#90417
I was able to solve your problems for the case you presented: a loop with a constant bound. The case of a dynamic bound is not yet supported. GCC seems to optimise only the constant case too. |
When looking at the loop counter, if the min/max values of the SCEV ranges are relevant (not extremal), add this information as ConditionFacts for the Loop header. It allows icmp simplifications independently of the branch taken, such as using `i <= N` after a block `for(i=0; i<N; i+=1) { ... }`. Fixes llvm#90417
When looking at the loop counter, if the min/max values of the SCEV ranges are relevant (not extremal), add this information as ConditionFacts for the Loop header. It allows icmp simplifications independently of the branch taken, such as using `i <= N` after a block `for(i=0; i<N; i+=1) { ... }`. Fixes llvm#90417 IMPORTANT: Concerning modifications to Polly One test for polly was modified as an icmp simplification could be done earlier in the pipeline than previously. The input of `polly::CodePreparationPass` is almost the same one, except the name of one block that is different because of this simplification done earlier.
When looking at the loop counter, if the min/max values of the SCEV ranges are relevant (not extremal), add this information as ConditionFacts for the Loop header. It allows icmp simplifications independently of the branch taken, such as using `i <= N` after a block `for(i=0; i<N; i+=1) { ... }`. Fixes llvm#90417 IMPORTANT: Concerning modifications to Polly One test for polly was modified as an icmp simplification could be done earlier in the pipeline than previously. The input of `polly::CodePreparationPass` is almost the same one, except the name of one block that is different because of this simplification done earlier.
When looking at the loop counter, if the min/max values of the SCEV ranges are relevant (not extremal), add this information as ConditionFacts for the Loop header. It allows icmp simplifications independently of the branch taken, such as using `i <= N` after a block `for(i=0; i<N; i+=1) { ... }`. Fixes llvm#90417 IMPORTANT: Concerning modifications to Polly One test for polly was modified as an icmp simplification could be done earlier in the pipeline than previously. The input of `polly::CodePreparationPass` is almost the same one, except the name of one block that is different because of this simplification done earlier.
For loops, we can use the condition in the loop header as upper bound on the compared induction in the unique exit block, if it exists. This can be done even if there are multiple in-loop edges to the unique exit block, as any other exit may only exit earlier. More generally, we could add the OR of all exit conditions to the exit, but that's a possible future extension. Fixes llvm#90417.
For loops, we can use the condition in the loop header as upper bound on the compared induction in the unique exit block, if it exists. This can be done even if there are multiple in-loop edges to the unique exit block, as any other exit may only exit earlier. More generally, we could add the OR of all exit conditions to the exit, but that's a possible future extension. Fixes llvm#90417.
For loops, we can use the condition in the loop header as upper bound on the compared induction in the unique exit block, if it exists. This can be done even if there are multiple in-loop edges to the unique exit block, as any other exit may only exit earlier. More generally, we could add the OR of all exit conditions to the exit, but that's a possible future extension. Fixes llvm#90417. !fixup properly handle non-monotonically increasing case.
For loops, we can use the condition in the loop header as upper bound on the compared induction in the unique exit block, if it exists. This can be done even if there are multiple in-loop edges to the unique exit block, as any other exit may only exit earlier. More generally, we could add the OR of all exit conditions to the exit, but that's a possible future extension. Fixes llvm#90417.
For loops, we can use the condition in the loop header as upper bound on the compared induction in the unique exit block, if it exists. This can be done even if there are multiple in-loop edges to the unique exit block, as any other exit may only exit earlier. More generally, we could add the OR of all exit conditions to the exit, but that's a possible future extension. Fixes llvm#90417. !fixup properly handle non-monotonically increasing case. !fixup always emit precondition, don't check unique predecessor
This old issue doesn't seem to be fixed as all: https://bugs.llvm.org/show_bug.cgi?id=49389
Bug 49389 would be reposted below (godbolt link: https://godbolt.org/z/hdza9Pb8z):
compiles to:
GCC is able to compile it to:
This is originally from: rust-lang/rust#81432
The text was updated successfully, but these errors were encountered: