This patch fixes two bugs: https://github.com/llvm/llvm-project/issues/41488 https://github.com/llvm/llvm-project/issues/53942 The dependence analysis assumes that the base address of array accesses is invariant across loop iterations. In both bugs the base address evolves following loop iterations: the base address flip-flops between two different memory objects. The patch uses the cross iteration mode of alias analysis to disambiguate the base objects.
160 lines
6.3 KiB
LLVM
160 lines
6.3 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: opt < %s -disable-output "-passes=print<da>" -aa-pipeline=basic-aa 2>&1 \
|
|
; RUN: | FileCheck %s
|
|
|
|
; Check that dependence analysis correctly handles flip-flop of base addresses.
|
|
; Bug 41488 - https://github.com/llvm/llvm-project/issues/41488
|
|
|
|
define float @bug41488_test1(float %f) {
|
|
; CHECK-LABEL: 'bug41488_test1'
|
|
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4
|
|
; CHECK-NEXT: da analyze - input [*]!
|
|
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float %f, ptr %q, align 4
|
|
; CHECK-NEXT: da analyze - confused!
|
|
; CHECK-NEXT: Src: store float %f, ptr %q, align 4 --> Dst: store float %f, ptr %q, align 4
|
|
; CHECK-NEXT: da analyze - output [*]!
|
|
;
|
|
entry:
|
|
%g = alloca float, align 4
|
|
%h = alloca float, align 4
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%p = phi float* [ %g, %entry ], [ %q, %for.body ]
|
|
%q = phi float* [ %h, %entry ], [ %p, %for.body ]
|
|
%0 = load float, float* %p, align 4
|
|
store float %f, float* %q, align 4
|
|
%branch_cond = fcmp ugt float %0, 0.0
|
|
br i1 %branch_cond, label %for.cond.cleanup, label %for.body
|
|
|
|
for.cond.cleanup:
|
|
ret float %f
|
|
}
|
|
|
|
define void @bug41488_test2(i32 %n) {
|
|
; CHECK-LABEL: 'bug41488_test2'
|
|
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: %0 = load float, ptr %p, align 4
|
|
; CHECK-NEXT: da analyze - input [*]!
|
|
; CHECK-NEXT: Src: %0 = load float, ptr %p, align 4 --> Dst: store float 0.000000e+00, ptr %q, align 4
|
|
; CHECK-NEXT: da analyze - confused!
|
|
; CHECK-NEXT: Src: store float 0.000000e+00, ptr %q, align 4 --> Dst: store float 0.000000e+00, ptr %q, align 4
|
|
; CHECK-NEXT: da analyze - output [*]!
|
|
;
|
|
entry:
|
|
%g = alloca float, align 4
|
|
%h = alloca float, align 4
|
|
br label %for.body
|
|
|
|
for.body:
|
|
%i = phi i32 [0, %entry ], [ %inc, %for.body ]
|
|
%p = phi float* [ %g, %entry ], [ %q, %for.body ]
|
|
%q = phi float* [ %h, %entry ], [ %p, %for.body ]
|
|
%0 = load float, float* %p, align 4
|
|
store float 0.0, float* %q, align 4
|
|
%inc = add nuw i32 %i, 1
|
|
%branch_cond = icmp ult i32 %i, %n
|
|
br i1 %branch_cond, label %for.body, label %for.cond.cleanup
|
|
|
|
for.cond.cleanup:
|
|
ret void
|
|
}
|
|
|
|
; Bug 53942 - https://github.com/llvm/llvm-project/issues/53942
|
|
|
|
define void @bug53942_foo(i32 noundef %n, ptr noalias nocapture noundef writeonly %A, ptr noalias nocapture noundef %B) {
|
|
; CHECK-LABEL: 'bug53942_foo'
|
|
; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: %.pre = load double, ptr %B, align 8
|
|
; CHECK-NEXT: da analyze - consistent input [S]!
|
|
; CHECK-NEXT: Src: %.pre = load double, ptr %B, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8
|
|
; CHECK-NEXT: da analyze - confused!
|
|
; CHECK-NEXT: Src: store double %.pre, ptr %arrayidx2, align 8 --> Dst: store double %.pre, ptr %arrayidx2, align 8
|
|
; CHECK-NEXT: da analyze - output [*]!
|
|
;
|
|
entry:
|
|
%cmp8 = icmp sgt i32 %n, 1
|
|
br i1 %cmp8, label %for.body.preheader, label %for.cond.cleanup
|
|
|
|
for.body.preheader: ; preds = %entry
|
|
%wide.trip.count = zext nneg i32 %n to i64
|
|
br label %for.body
|
|
|
|
for.cond.cleanup: ; preds = %for.body, %entry
|
|
ret void
|
|
|
|
for.body: ; preds = %for.body.preheader, %for.body
|
|
%indvars.iv = phi i64 [ 1, %for.body.preheader ], [ %indvars.iv.next, %for.body ]
|
|
%ptr1.011 = phi ptr [ %A, %for.body.preheader ], [ %ptr2.09, %for.body ]
|
|
%ptr2.09 = phi ptr [ %B, %for.body.preheader ], [ %ptr1.011, %for.body ]
|
|
%.pre = load double, ptr %B, align 8
|
|
%arrayidx2 = getelementptr inbounds double, ptr %ptr1.011, i64 %indvars.iv
|
|
store double %.pre, ptr %arrayidx2, align 8
|
|
%indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
|
|
%exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count
|
|
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
|
|
}
|
|
|
|
|
|
; Bug 53942 - https://github.com/llvm/llvm-project/issues/53942
|
|
|
|
define void @bug53942_bar(i32 noundef %n, ptr noalias noundef %A, ptr noalias noundef %B) {
|
|
; CHECK-LABEL: 'bug53942_bar'
|
|
; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: %0 = load double, ptr %arrayidx, align 8
|
|
; CHECK-NEXT: da analyze - input [*]!
|
|
; CHECK-NEXT: Src: %0 = load double, ptr %arrayidx, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8
|
|
; CHECK-NEXT: da analyze - confused!
|
|
; CHECK-NEXT: Src: store double %0, ptr %arrayidx8, align 8 --> Dst: store double %0, ptr %arrayidx8, align 8
|
|
; CHECK-NEXT: da analyze - output [*]!
|
|
;
|
|
entry:
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.inc, %entry
|
|
%i.0 = phi i32 [ 1, %entry ], [ %inc, %for.inc ]
|
|
%cmp = icmp slt i32 %i.0, %n
|
|
br i1 %cmp, label %for.body, label %for.cond.cleanup
|
|
|
|
for.cond.cleanup: ; preds = %for.cond
|
|
br label %for.end
|
|
|
|
for.body: ; preds = %for.cond
|
|
%and = and i32 %i.0, 2
|
|
%tobool.not = icmp eq i32 %and, 0
|
|
br i1 %tobool.not, label %cond.false, label %cond.true
|
|
|
|
cond.true: ; preds = %for.body
|
|
br label %cond.end
|
|
|
|
cond.false: ; preds = %for.body
|
|
br label %cond.end
|
|
|
|
cond.end: ; preds = %cond.false, %cond.true
|
|
%cond = phi ptr [ %A, %cond.true ], [ %B, %cond.false ]
|
|
%and1 = and i32 %i.0, 2
|
|
%tobool2.not = icmp eq i32 %and1, 0
|
|
br i1 %tobool2.not, label %cond.false4, label %cond.true3
|
|
|
|
cond.true3: ; preds = %cond.end
|
|
br label %cond.end5
|
|
|
|
cond.false4: ; preds = %cond.end
|
|
br label %cond.end5
|
|
|
|
cond.end5: ; preds = %cond.false4, %cond.true3
|
|
%cond6 = phi ptr [ %B, %cond.true3 ], [ %A, %cond.false4 ]
|
|
%sub = add nsw i32 %i.0, -1
|
|
%idxprom = sext i32 %sub to i64
|
|
%arrayidx = getelementptr inbounds double, ptr %cond6, i64 %idxprom
|
|
%0 = load double, ptr %arrayidx, align 8
|
|
%idxprom7 = zext nneg i32 %i.0 to i64
|
|
%arrayidx8 = getelementptr inbounds double, ptr %cond, i64 %idxprom7
|
|
store double %0, ptr %arrayidx8, align 8
|
|
br label %for.inc
|
|
|
|
for.inc: ; preds = %cond.end5
|
|
%inc = add nuw nsw i32 %i.0, 1
|
|
br label %for.cond
|
|
|
|
for.end: ; preds = %for.cond.cleanup
|
|
ret void
|
|
}
|