[llvm] 73cd3d4 - [LSR] Prevent creating SCEVs of addrecs from mismatching loops

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 22 14:50:42 PST 2023


Author: David Green
Date: 2023-02-22T22:50:37Z
New Revision: 73cd3d4391ad47ae72028d4d01df0865b033dfed

URL: https://github.com/llvm/llvm-project/commit/73cd3d4391ad47ae72028d4d01df0865b033dfed
DIFF: https://github.com/llvm/llvm-project/commit/73cd3d4391ad47ae72028d4d01df0865b033dfed.diff

LOG: [LSR] Prevent creating SCEVs of addrecs from mismatching loops

LSR can include Regs of AddRec SCEVs from different loops, which do not combine
well when added in Scalar Evolution. As they should never produce constant
differences so we can just guard against trying to create them.

Fixes #60927

Added: 
    llvm/test/CodeGen/X86/lsr-addrecloops.ll

Modified: 
    llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
index 3045bd935f49e..3887533f396d1 100644
--- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
+++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp
@@ -4989,7 +4989,10 @@ static bool IsSimplerBaseSCEVForTarget(const TargetTransformInfo &TTI,
                                        ScalarEvolution &SE, const SCEV *Best,
                                        const SCEV *Reg,
                                        MemAccessTy AccessType) {
-  if (Best->getType() != Reg->getType())
+  if (Best->getType() != Reg->getType() ||
+      (false && isa<SCEVAddRecExpr>(Best) && isa<SCEVAddRecExpr>(Reg) &&
+       cast<SCEVAddRecExpr>(Best)->getLoop() !=
+           cast<SCEVAddRecExpr>(Reg)->getLoop()))
     return false;
   const auto *Diff = dyn_cast<SCEVConstant>(SE.getMinusSCEV(Best, Reg));
   if (!Diff)

diff  --git a/llvm/test/CodeGen/X86/lsr-addrecloops.ll b/llvm/test/CodeGen/X86/lsr-addrecloops.ll
new file mode 100644
index 0000000000000..76e8d4c86eb07
--- /dev/null
+++ b/llvm/test/CodeGen/X86/lsr-addrecloops.ll
@@ -0,0 +1,218 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s | FileCheck %s
+
+; Check that the SCEVs produced from the multiple loops don't attempt to get
+; combines in invalid ways. The LSR filtering could attempt to combine addrecs
+; from 
diff erent loops.
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @in4dob_(ptr nocapture writeonly %0, ptr nocapture readonly %1, ptr nocapture readonly %2, i64 %3, i1 %min.iters.check840) {
+; CHECK-LABEL: in4dob_:
+; CHECK:       .LBB0_6: # %vector.body807
+; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    leaq (%rdi,%r10), %rbx
+; CHECK-NEXT:    movups %xmm0, -80(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -96(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -79(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -95(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -78(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -94(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -77(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -93(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -76(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -92(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -75(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -91(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -74(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -90(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -73(%rbx,%r9,4)
+; CHECK-NEXT:    movups %xmm0, -89(%rbx,%r9,4)
+; CHECK-NEXT:    addq $8, %r10
+; CHECK-NEXT:    cmpq %r10, %r11
+; CHECK-NEXT:    jne .LBB0_6
+; CHECK:       .LBB0_14: # %vector.body847
+; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
+; CHECK-NEXT:    leaq (%rdi,%rcx), %r8
+; CHECK-NEXT:    movups %xmm0, 16(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, (%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 17(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 1(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 18(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 2(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 19(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 3(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 20(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 4(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 21(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 5(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 22(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 6(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 23(%r8,%r9,4)
+; CHECK-NEXT:    movups %xmm0, 7(%r8,%r9,4)
+.preheader263:
+  %4 = shl i64 %3, 2
+  br label %5
+
+5:                                                ; preds = %16, %.preheader263
+  %lsr.iv1135 = phi ptr [ %0, %.preheader263 ], [ %uglygep1136, %16 ]
+  %indvars.iv487 = phi i64 [ 1, %.preheader263 ], [ %indvars.iv.next488, %16 ]
+  %6 = getelementptr float, ptr %1, i64 %indvars.iv487
+  %7 = load float, ptr %6, align 4
+  %8 = fcmp oeq float %7, 0.000000e+00
+  %9 = getelementptr float, ptr %2, i64 %indvars.iv487
+  %10 = load float, ptr %9, align 4
+  %11 = fcmp oeq float %10, 0.000000e+00
+  %12 = and i1 %8, %11
+  br i1 %12, label %vector.body807.preheader, label %16
+
+vector.body807.preheader:                         ; preds = %5
+  %13 = add i64 %3, 1
+  %xtraiter = and i64 %13, 7
+  %14 = icmp ult i64 %3, 7
+  br i1 %14, label %.lr.ph373.unr-lcssa, label %vector.body807.preheader.new
+
+vector.body807.preheader.new:                     ; preds = %vector.body807.preheader
+  %unroll_iter = and i64 %13, -8
+  br label %vector.body807
+
+vector.body807:                                   ; preds = %vector.body807, %vector.body807.preheader.new
+  %lsr.iv1194 = phi i64 [ 0, %vector.body807.preheader.new ], [ %lsr.iv.next1195.7, %vector.body807 ]
+  %niter = phi i64 [ 0, %vector.body807.preheader.new ], [ %niter.next.7, %vector.body807 ]
+  %uglygep1197 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv1194
+  store <8 x float> zeroinitializer, ptr %uglygep1197, align 4
+  %lsr.iv.next1195 = or i64 %lsr.iv1194, 1
+  %uglygep1197.1 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv.next1195
+  store <8 x float> zeroinitializer, ptr %uglygep1197.1, align 4
+  %lsr.iv.next1195.1 = or i64 %lsr.iv1194, 2
+  %uglygep1197.2 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv.next1195.1
+  store <8 x float> zeroinitializer, ptr %uglygep1197.2, align 4
+  %lsr.iv.next1195.2 = or i64 %lsr.iv1194, 3
+  %uglygep1197.3 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv.next1195.2
+  store <8 x float> zeroinitializer, ptr %uglygep1197.3, align 4
+  %lsr.iv.next1195.3 = or i64 %lsr.iv1194, 4
+  %uglygep1197.4 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv.next1195.3
+  store <8 x float> zeroinitializer, ptr %uglygep1197.4, align 4
+  %lsr.iv.next1195.4 = or i64 %lsr.iv1194, 5
+  %uglygep1197.5 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv.next1195.4
+  store <8 x float> zeroinitializer, ptr %uglygep1197.5, align 4
+  %lsr.iv.next1195.5 = or i64 %lsr.iv1194, 6
+  %uglygep1197.6 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv.next1195.5
+  store <8 x float> zeroinitializer, ptr %uglygep1197.6, align 4
+  %lsr.iv.next1195.6 = or i64 %lsr.iv1194, 7
+  %uglygep1197.7 = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv.next1195.6
+  store <8 x float> zeroinitializer, ptr %uglygep1197.7, align 4
+  %lsr.iv.next1195.7 = add i64 %lsr.iv1194, 8
+  %niter.next.7 = add i64 %niter, 8
+  %niter.ncmp.7 = icmp eq i64 %niter.next.7, %unroll_iter
+  br i1 %niter.ncmp.7, label %.lr.ph373.unr-lcssa.loopexit, label %vector.body807
+
+.lr.ph373.unr-lcssa.loopexit:                     ; preds = %vector.body807
+  br label %.lr.ph373.unr-lcssa
+
+.lr.ph373.unr-lcssa:                              ; preds = %.lr.ph373.unr-lcssa.loopexit, %vector.body807.preheader
+  %lsr.iv1194.unr = phi i64 [ 0, %vector.body807.preheader ], [ %lsr.iv.next1195.7, %.lr.ph373.unr-lcssa.loopexit ]
+  %lcmp.mod.not = icmp eq i64 %xtraiter, 0
+  br i1 %lcmp.mod.not, label %.lr.ph373, label %vector.body807.epil.preheader
+
+vector.body807.epil.preheader:                    ; preds = %.lr.ph373.unr-lcssa
+  br label %vector.body807.epil
+
+vector.body807.epil:                              ; preds = %vector.body807.epil.preheader, %vector.body807.epil
+  %lsr.iv1194.epil = phi i64 [ %lsr.iv.next1195.epil, %vector.body807.epil ], [ %lsr.iv1194.unr, %vector.body807.epil.preheader ]
+  %epil.iter = phi i64 [ %epil.iter.next, %vector.body807.epil ], [ 0, %vector.body807.epil.preheader ]
+  %uglygep1197.epil = getelementptr i8, ptr %lsr.iv1135, i64 %lsr.iv1194.epil
+  store <8 x float> zeroinitializer, ptr %uglygep1197.epil, align 4
+  %lsr.iv.next1195.epil = add i64 %lsr.iv1194.epil, 1
+  %epil.iter.next = add i64 %epil.iter, 1
+  %epil.iter.cmp.not = icmp eq i64 %epil.iter.next, %xtraiter
+  br i1 %epil.iter.cmp.not, label %.lr.ph373.loopexit, label %vector.body807.epil
+
+.lr.ph373.loopexit:                               ; preds = %vector.body807.epil
+  br label %.lr.ph373
+
+.lr.ph373:                                        ; preds = %.lr.ph373.loopexit, %.lr.ph373.unr-lcssa
+  br i1 %min.iters.check840, label %scalar.ph839.preheader, label %vector.body847.preheader
+
+vector.body847.preheader:                         ; preds = %.lr.ph373
+  %uglygep11551 = getelementptr i8, ptr %lsr.iv1135, i64 96
+  %xtraiter12 = and i64 %13, 7
+  %15 = icmp ult i64 %3, 7
+  br i1 %15, label %common.ret.loopexit.unr-lcssa, label %vector.body847.preheader.new
+
+vector.body847.preheader.new:                     ; preds = %vector.body847.preheader
+  %unroll_iter15 = and i64 %13, -8
+  br label %vector.body847
+
+vector.body847:                                   ; preds = %vector.body847, %vector.body847.preheader.new
+  %lsr.iv1152 = phi i64 [ 0, %vector.body847.preheader.new ], [ %lsr.iv.next1153.7, %vector.body847 ]
+  %niter16 = phi i64 [ 0, %vector.body847.preheader.new ], [ %niter16.next.7, %vector.body847 ]
+  %uglygep1156 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv1152
+  store <8 x float> zeroinitializer, ptr %uglygep1156, align 4
+  %lsr.iv.next1153 = or i64 %lsr.iv1152, 1
+  %uglygep1156.1 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv.next1153
+  store <8 x float> zeroinitializer, ptr %uglygep1156.1, align 4
+  %lsr.iv.next1153.1 = or i64 %lsr.iv1152, 2
+  %uglygep1156.2 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv.next1153.1
+  store <8 x float> zeroinitializer, ptr %uglygep1156.2, align 4
+  %lsr.iv.next1153.2 = or i64 %lsr.iv1152, 3
+  %uglygep1156.3 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv.next1153.2
+  store <8 x float> zeroinitializer, ptr %uglygep1156.3, align 4
+  %lsr.iv.next1153.3 = or i64 %lsr.iv1152, 4
+  %uglygep1156.4 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv.next1153.3
+  store <8 x float> zeroinitializer, ptr %uglygep1156.4, align 4
+  %lsr.iv.next1153.4 = or i64 %lsr.iv1152, 5
+  %uglygep1156.5 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv.next1153.4
+  store <8 x float> zeroinitializer, ptr %uglygep1156.5, align 4
+  %lsr.iv.next1153.5 = or i64 %lsr.iv1152, 6
+  %uglygep1156.6 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv.next1153.5
+  store <8 x float> zeroinitializer, ptr %uglygep1156.6, align 4
+  %lsr.iv.next1153.6 = or i64 %lsr.iv1152, 7
+  %uglygep1156.7 = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv.next1153.6
+  store <8 x float> zeroinitializer, ptr %uglygep1156.7, align 4
+  %lsr.iv.next1153.7 = add i64 %lsr.iv1152, 8
+  %niter16.next.7 = add i64 %niter16, 8
+  %niter16.ncmp.7 = icmp eq i64 %niter16.next.7, %unroll_iter15
+  br i1 %niter16.ncmp.7, label %common.ret.loopexit.unr-lcssa.loopexit, label %vector.body847
+
+common.ret.loopexit.unr-lcssa.loopexit:           ; preds = %vector.body847
+  br label %common.ret.loopexit.unr-lcssa
+
+common.ret.loopexit.unr-lcssa:                    ; preds = %common.ret.loopexit.unr-lcssa.loopexit, %vector.body847.preheader
+  %lsr.iv1152.unr = phi i64 [ 0, %vector.body847.preheader ], [ %lsr.iv.next1153.7, %common.ret.loopexit.unr-lcssa.loopexit ]
+  %lcmp.mod14.not = icmp eq i64 %xtraiter12, 0
+  br i1 %lcmp.mod14.not, label %common.ret, label %vector.body847.epil.preheader
+
+vector.body847.epil.preheader:                    ; preds = %common.ret.loopexit.unr-lcssa
+  br label %vector.body847.epil
+
+vector.body847.epil:                              ; preds = %vector.body847.epil.preheader, %vector.body847.epil
+  %lsr.iv1152.epil = phi i64 [ %lsr.iv.next1153.epil, %vector.body847.epil ], [ %lsr.iv1152.unr, %vector.body847.epil.preheader ]
+  %epil.iter13 = phi i64 [ %epil.iter13.next, %vector.body847.epil ], [ 0, %vector.body847.epil.preheader ]
+  %uglygep1156.epil = getelementptr i8, ptr %uglygep11551, i64 %lsr.iv1152.epil
+  store <8 x float> zeroinitializer, ptr %uglygep1156.epil, align 4
+  %lsr.iv.next1153.epil = add i64 %lsr.iv1152.epil, 1
+  %epil.iter13.next = add i64 %epil.iter13, 1
+  %epil.iter13.cmp.not = icmp eq i64 %epil.iter13.next, %xtraiter12
+  br i1 %epil.iter13.cmp.not, label %common.ret.loopexit, label %vector.body847.epil
+
+common.ret.loopexit:                              ; preds = %vector.body847.epil
+  br label %common.ret
+
+common.ret.loopexit1:                             ; preds = %16
+  br label %common.ret
+
+common.ret:                                       ; preds = %common.ret.loopexit1, %common.ret.loopexit, %scalar.ph839.preheader, %common.ret.loopexit.unr-lcssa
+  ret void
+
+scalar.ph839.preheader:                           ; preds = %.lr.ph373
+  store float 0.000000e+00, ptr %0, align 4
+  br label %common.ret
+
+16:                                               ; preds = %5
+  %indvars.iv.next488 = add i64 %indvars.iv487, 1
+  %exitcond492.not = icmp eq i64 %indvars.iv.next488, %3
+  %uglygep1136 = getelementptr i8, ptr %lsr.iv1135, i64 %4
+  br i1 %exitcond492.not, label %common.ret.loopexit1, label %5
+}


        


More information about the llvm-commits mailing list