diff --git a/llvm/lib/Analysis/LoopAccessAnalysis.cpp b/llvm/lib/Analysis/LoopAccessAnalysis.cpp index 38e9145826c08..2a68979add666 100644 --- a/llvm/lib/Analysis/LoopAccessAnalysis.cpp +++ b/llvm/lib/Analysis/LoopAccessAnalysis.cpp @@ -1921,6 +1921,7 @@ MemoryDepChecker::getDependenceDistanceStrideAndSize( if (StrideAPtr && *StrideAPtr < 0) { std::swap(Src, Sink); std::swap(AInst, BInst); + std::swap(ATy, BTy); std::swap(StrideAPtr, StrideBPtr); } diff --git a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll index 0bdcc35790148..e855578e794fa 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/depend_diff_types.ll @@ -194,3 +194,79 @@ loop: exit: ret void } + +; In the following test, the sink is loop-invariant. + +define void @type_size_equivalence_sink_loopinv(ptr nocapture %vec, i64 %n) { +; CHECK-LABEL: 'type_size_equivalence_sink_loopinv' +; CHECK-NEXT: loop: +; CHECK-NEXT: Memory dependences are safe +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + %gep.n = getelementptr inbounds i64, ptr %vec, i64 %n + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] + + %gep.iv = getelementptr i64, ptr %vec, i64 %iv + %ld.i64 = load i64, ptr %gep.iv, align 8 + + %ld.i64.i32 = trunc i64 %ld.i64 to i32 + store i32 %ld.i64.i32, ptr %gep.n, align 8 + + %iv.next = add nuw nsw i64 %iv, 1 + %cond = icmp eq i64 %iv.next, %n + br i1 %cond, label %exit, label %loop + +exit: + ret void +} + +; Variant of the above, with a negative induction step and a gep exposing +; type-mismtach. + +define void @type_size_equivalence_sink_loopinv_negind(ptr nocapture %vec, i64 %n) { +; CHECK-LABEL: 'type_size_equivalence_sink_loopinv_negind' +; CHECK-NEXT: loop: +; CHECK-NEXT: Memory dependences are safe +; CHECK-NEXT: Dependences: +; CHECK-NEXT: Run-time memory checks: +; CHECK-NEXT: Grouped accesses: +; CHECK-EMPTY: +; CHECK-NEXT: Non vectorizable stores to invariant address were not found in loop. +; CHECK-NEXT: SCEV assumptions: +; CHECK-EMPTY: +; CHECK-NEXT: Expressions re-written: +; +entry: + %minus.n = sub nsw i64 0, %n + %gep.minus.n = getelementptr inbounds i64, ptr %vec, i64 %minus.n + br label %loop + +loop: + %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] + + %minus.iv = sub nsw i64 0, %iv + %gep.minus.iv = getelementptr i64, ptr %vec, i64 %minus.iv + %gep.minus.iv.4 = getelementptr i8, ptr %gep.minus.iv, i64 -4 + %ld.i64 = load i64, ptr %gep.minus.iv.4, align 8 + + %ld.i64.i32 = trunc i64 %ld.i64 to i32 + store i32 %ld.i64.i32, ptr %gep.minus.n, align 8 + + %iv.next = add nuw nsw i64 %iv, 1 + %cond = icmp eq i64 %iv.next, %n + br i1 %cond, label %exit, label %loop + +exit: + ret void +}