Issue |
90937
|
Summary |
Miscompile loop-interchange pass because of GEP delinealization.
|
Labels |
new issue
|
Assignees |
|
Reporter |
sanggyu-shin
|
Following code is loop interchangable but current llvm can't do it.
```
for (int i = 0; i < LEN_2D; ++i)
for (int j = 1; j < LEN_2D; j++)
aa[j][i] = aa[j - 1][i] + bb[j][i];
```
I found that there is a problem about delinealization after LICM pass.
Here is llvm ir after LICM pass:
```
define dso_local void @func(ptr nocapture noundef %aa, ptr nocapture noundef readonly %bb) local_unnamed_addr #0 {
entry:
%invariant.gep = getelementptr i8, ptr %aa, i64 -8000
br label %for.cond1.preheader
for.cond1.preheader: ; preds = %entry, %for.cond.cleanup3
%indvars.iv31 = phi i64 [ 0, %entry ], [ %indvars.iv.next32, %for.cond.cleanup3 ]
%invariant.gep27 = getelementptr [1000 x double], ptr %invariant.gep, i64 0, i64 %indvars.iv31
br label %for.body4
for.cond.cleanup: ; preds = %for.cond.cleanup3
ret void
for.cond.cleanup3: ; preds = %for.body4
%indvars.iv.next32 = add nuw nsw i64 %indvars.iv31, 1
%exitcond33 = icmp ne i64 %indvars.iv.next32, 1000
br i1 %exitcond33, label %for.cond1.preheader, label %for.cond.cleanup
for.body4: ; preds = %for.cond1.preheader, %for.body4
%indvars.iv = phi i64 [ 1, %for.cond1.preheader ], [ %indvars.iv.next, %for.body4 ]
%gep28 = getelementptr [1000 x double], ptr %invariant.gep27, i64 %indvars.iv
%0 = load double, ptr %gep28, align 8
%arrayidx10 = getelementptr inbounds [1000 x double], ptr %bb, i64 %indvars.iv, i64 %indvars.iv31
%1 = load double, ptr %arrayidx10, align 8
%add = fadd double %0, %1
%arrayidx14 = getelementptr inbounds [1000 x double], ptr %aa, i64 %indvars.iv, i64 %indvars.iv31
store double %add, ptr %arrayidx14, align 8
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
%exitcond = icmp ne i64 %indvars.iv.next, 1000
br i1 %exitcond, label %for.body4, label %for.cond.cleanup3
}
```
run commend:
```
$ opt loop-interchange.bc -debug -passes=loop-interchange -pass-remarks-missed='loop-interchange' -o test.bc
remark: <unknown>:0:0: Cannot interchange loops due to dependences.
```
Debug print out:
```
Delinearizing: %0 = load double, ptr %gep28, align 8
In Loop 'for.body4', AccessFn: {{0,+,8}<nuw><nsw><%for.cond1.preheader>,+,8000}<%for.body4>
Strides:
8000
8
Terms:
ERROR: failed to delinearize reference
```
Delinealization got faild when the source is from multiple GEP.
For example, in ```%0 = load``` in ```for.body4```, the source is ```%gep28```.
But, the problem is that the source of ```gep28``` is also GEP(```$invariant.gep27```)
Actually, the original gep (before LICM) had two indices but gep28 has only one index after LICM.
Current delinealization can't track the recursive gep instructions. So, it can't know exact subscripts.
I would like to discuss the root cause and what part should be modified because I'm not an expert of LLVM.
I think there are two approaches to fix this problem.
1) Modify delinealization - support recursive GEP.
2) Modify LICM.
Please give me an idea if you have any suggestions.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs