[llvm] [LoopFlatten] Invalidate SCEV on each widening (PR #211819)

Arda Serdar Pektezol via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 07:27:25 PDT 2026


================
@@ -0,0 +1,94 @@
+; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes='loop(loop-flatten),print<scalar-evolution>' -disable-output 2>&1 | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define i64 @f(i64 %n) {
+; CHECK-LABEL: 'f'
+; CHECK-NEXT:  Classifying expressions for: @f
+; CHECK-NEXT:    %i = phi i64 [ 0, %entry ], [ %i.next, %outer.latch ]
+; CHECK-NEXT:    --> {0,+,1}<nuw><%outer.loop> U: full-set S: full-set Exits: %n LoopDispositions: { %outer.loop: Computable, %mid.loop: Invariant, %inner.loop: Invariant }
+; CHECK-NEXT:    %tc = trunc i64 %i to i32
+; CHECK-NEXT:    --> {0,+,1}<%outer.loop> U: full-set S: full-set Exits: (trunc i64 %n to i32) LoopDispositions: { %outer.loop: Computable, %mid.loop: Invariant, %inner.loop: Invariant }
+; CHECK-NEXT:    %0 = zext i32 %tc to i64
+; CHECK-NEXT:    --> (zext i32 {0,+,1}<%outer.loop> to i64) U: [0,4294967296) S: [0,4294967296) Exits: (zext i32 (trunc i64 %n to i32) to i64) LoopDispositions: { %outer.loop: Computable, %mid.loop: Invariant, %inner.loop: Invariant }
+; CHECK-NEXT:    %1 = sext i32 %tc to i64
+; CHECK-NEXT:    --> (sext i32 {0,+,1}<%outer.loop> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: (sext i32 (trunc i64 %n to i32) to i64) LoopDispositions: { %outer.loop: Computable, %mid.loop: Invariant, %inner.loop: Invariant }
+; CHECK-NEXT:    %indvar1 = phi i64 [ 0, %mid.loop.preheader ], [ %indvar.next2, %mid.latch ]
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%mid.loop> U: [0,1) S: [0,1) Exits: 0 LoopDispositions: { %mid.loop: Computable, %outer.loop: Uniform, %inner.loop: Invariant }
+; CHECK-NEXT:    %k = phi i32 [ %k.next, %mid.latch ], [ 0, %mid.loop.preheader ]
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%mid.loop> U: [0,1) S: [0,1) Exits: 0 LoopDispositions: { %mid.loop: Computable, %outer.loop: Uniform, %inner.loop: Invariant }
+; CHECK-NEXT:    %indvar = phi i64 [ %indvar.next, %inner.loop ], [ 0, %mid.loop ]
+; CHECK-NEXT:    --> {0,+,1}<nuw><nsw><%inner.loop> U: [0,4294967295) S: [0,4294967295) Exits: (-1 + (zext i32 {0,+,1}<%outer.loop> to i64))<nsw> LoopDispositions: { %inner.loop: Computable, %mid.loop: Uniform, %outer.loop: Uniform }
+; CHECK-NEXT:    %2 = mul i64 %indvar1, %1
+; CHECK-NEXT:    --> {0,+,(sext i32 {0,+,1}<%outer.loop> to i64)}<nsw><%mid.loop> U: [0,1) S: [0,1) Exits: {0,+,(sext i32 {0,+,1}<%outer.loop> to i64)}<nuw><nsw><%mid.loop> LoopDispositions: { %inner.loop: Invariant, %mid.loop: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    %mul = mul i32 %k, %tc
+; CHECK-NEXT:    --> {0,+,{0,+,1}<%outer.loop>}<nsw><%mid.loop> U: [0,1) S: [0,1) Exits: {0,+,{0,+,1}<%outer.loop>}<nuw><nsw><%mid.loop> LoopDispositions: { %inner.loop: Invariant, %mid.loop: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    %3 = trunc nuw nsw i64 %2 to i32
+; CHECK-NEXT:    --> {0,+,{0,+,1}<%outer.loop>}<nuw><nsw><%mid.loop> U: [0,1) S: [0,1) Exits: {0,+,{0,+,1}<%outer.loop>}<nuw><nsw><%mid.loop> LoopDispositions: { %inner.loop: Invariant, %mid.loop: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    %gep = getelementptr i32, ptr null, i32 %3
+; CHECK-NEXT:    --> {null,+,(4 * (sext i32 {0,+,1}<%outer.loop> to i64))<nsw>}<nw><%mid.loop> U: [0,1) S: [0,1) Exits: {null,+,(4 * (sext i32 {0,+,1}<%outer.loop> to i64))<nsw>}<nuw><nsw><%mid.loop> LoopDispositions: { %inner.loop: Invariant, %mid.loop: Computable, %outer.loop: Variant }
+; CHECK-NEXT:    %4 = trunc nuw i64 %indvar to i32
+; CHECK-NEXT:    --> {0,+,1}<nuw><%inner.loop> U: [0,-1) S: [0,-1) Exits: {-1,+,1}<%outer.loop> LoopDispositions: { %inner.loop: Computable, %mid.loop: Uniform, %outer.loop: Uniform }
+; CHECK-NEXT:    %arrayidx = getelementptr i32, ptr %gep, i32 %4
+; CHECK-NEXT:    --> ((4 * (sext i32 {0,+,1}<nuw><%inner.loop> to i64))<nsw> + {null,+,(4 * (sext i32 {0,+,1}<%outer.loop> to i64))<nsw>}<nuw><nsw><%mid.loop>) U: [0,-3) S: [-8589934592,8589934589) Exits: {((4 * (sext i32 {-1,+,1}<%outer.loop> to i64))<nsw> + null),+,(4 * (sext i32 {0,+,1}<%outer.loop> to i64))<nsw>}<nw><%mid.loop> LoopDispositions: { %inner.loop: Computable, %mid.loop: Variant, %outer.loop: Variant }
+; CHECK-NEXT:    %indvar.next = add i64 %indvar, 1
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%inner.loop> U: [1,4294967296) S: [1,4294967296) Exits: (zext i32 {0,+,1}<%outer.loop> to i64) LoopDispositions: { %inner.loop: Computable, %mid.loop: Uniform, %outer.loop: Uniform }
+; CHECK-NEXT:    %indvar.next2 = add i64 %indvar1, 1
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%mid.loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %mid.loop: Computable, %outer.loop: Uniform, %inner.loop: Invariant }
+; CHECK-NEXT:    %k.next = add i32 %k, 1
+; CHECK-NEXT:    --> {1,+,1}<nuw><nsw><%mid.loop> U: [1,2) S: [1,2) Exits: 1 LoopDispositions: { %mid.loop: Computable, %outer.loop: Uniform, %inner.loop: Invariant }
+; CHECK-NEXT:    %i.next = add i64 %i, 1
+; CHECK-NEXT:    --> {1,+,1}<nw><%outer.loop> U: full-set S: full-set Exits: (1 + %n) LoopDispositions: { %outer.loop: Computable, %mid.loop: Invariant, %inner.loop: Invariant }
+; CHECK-NEXT:  Determining loop execution counts for: @f
+; CHECK-NEXT:  Loop %inner.loop: backedge-taken count is (-1 + (zext i32 {0,+,1}<%outer.loop> to i64))<nsw>
+; CHECK-NEXT:  Loop %inner.loop: constant max backedge-taken count is i64 4294967294
+; CHECK-NEXT:  Loop %inner.loop: symbolic max backedge-taken count is (-1 + (zext i32 {0,+,1}<%outer.loop> to i64))<nsw>
+; CHECK-NEXT:  Loop %inner.loop: Trip multiple is 1
+; CHECK-NEXT:  Loop %mid.loop: backedge-taken count is i1 false
+; CHECK-NEXT:  Loop %mid.loop: constant max backedge-taken count is i1 false
+; CHECK-NEXT:  Loop %mid.loop: symbolic max backedge-taken count is i1 false
+; CHECK-NEXT:  Loop %mid.loop: Trip multiple is 1
+; CHECK-NEXT:  Loop %outer.loop: backedge-taken count is %n
+; CHECK-NEXT:  Loop %outer.loop: constant max backedge-taken count is i64 -1
+; CHECK-NEXT:  Loop %outer.loop: symbolic max backedge-taken count is %n
+; CHECK-NEXT:  Loop %outer.loop: Trip multiple is 1
+;
+entry:
+  br label %outer.loop
+
+outer.loop:                                       ; preds = %outer.latch, %entry
+  %i = phi i64 [ 0, %entry ], [ %i.next, %outer.latch ]
+  %outer.cond = icmp ult i64 %i, %n
+  br i1 %outer.cond, label %outer.body, label %exit
+
+outer.body:                                       ; preds = %outer.loop
+  %tc = trunc i64 %i to i32
+  br i1 false, label %mid.loop, label %outer.latch
+
+mid.loop:                                         ; preds = %mid.latch, %outer.body
+  %k = phi i32 [ %k.next, %mid.latch ], [ 0, %outer.body ]
+  br label %inner.loop
+
+inner.loop:                                       ; preds = %inner.loop, %mid.loop
+  %j = phi i32 [ 0, %mid.loop ], [ %j.next, %inner.loop ]
+  %mul = mul i32 %k, %tc
+  %gep = getelementptr i32, ptr null, i32 %mul
----------------
pektezol wrote:

Updated.

https://github.com/llvm/llvm-project/pull/211819


More information about the llvm-commits mailing list