[SCEV] Add additional tests.
authorFlorian Hahn <flo@fhahn.com>
Sun, 12 Jul 2020 22:05:43 +0000 (23:05 +0100)
committerFlorian Hahn <flo@fhahn.com>
Tue, 28 Jul 2020 15:15:57 +0000 (16:15 +0100)
Increase test coverage for upcoming changes to how SCEV deals with LCSSA
phis.

llvm/test/Analysis/ScalarEvolution/trivial-phis.ll [new file with mode: 0644]
llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll [new file with mode: 0644]
llvm/test/Transforms/LoopStrengthReduce/funclet.ll
llvm/test/Transforms/LoopStrengthReduce/scev-expander-lcssa.ll [new file with mode: 0644]

diff --git a/llvm/test/Analysis/ScalarEvolution/trivial-phis.ll b/llvm/test/Analysis/ScalarEvolution/trivial-phis.ll
new file mode 100644 (file)
index 0000000..3a897e9
--- /dev/null
@@ -0,0 +1,191 @@
+; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s
+
+; CHECK-LABEL @test1
+; CHECK       %add.lcssa.wide = phi i64 [ %indvars.iv.next, %do.body ]
+; CHECK-NEXT  -->  %add.lcssa.wide U: [1,2147483648) S: [1,2147483648)
+
+define i64 @test1(i32 signext %n, float* %A) {
+entry:
+  %0 = sext i32 %n to i64
+  br label %do.body
+
+do.body:                                          ; preds = %do.body, %entry
+  %indvars.iv = phi i64 [ %indvars.iv.next, %do.body ], [ 0, %entry ]
+  %arrayidx = getelementptr inbounds float, float* %A, i64 %indvars.iv
+  store float 1.000000e+00, float* %arrayidx, align 4
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  %cmp = icmp slt i64 %indvars.iv.next, %0
+  br i1 %cmp, label %do.body, label %do.end
+
+do.end:                                           ; preds = %do.body
+  %add.lcssa.wide = phi i64 [ %indvars.iv.next, %do.body ]
+  ret i64 %add.lcssa.wide
+}
+
+; CHECK-LABEL @test2
+; CHECK:      %tmp24 = phi i64 [ %tmp14, %bb22 ], [ %tmp14, %bb13 ]
+; CHECK-NEXT: -->  %tmp24 U: full-set S: full-set       Exits: <<Unknown>>      LoopDispositions: { %bb13: Variant, %bb8: Variant, %bb17: Invariant, %bb27: Invariant }
+
+define void @test2(i64 %arg, i32* noalias %arg1) {
+bb:
+  %tmp = icmp slt i64 0, %arg
+  br i1 %tmp, label %bb7, label %bb48
+
+bb7:                                              ; preds = %bb
+  br label %bb8
+
+bb8:                                              ; preds = %bb44, %bb7
+  %tmp9 = phi i64 [ 0, %bb7 ], [ %tmp45, %bb44 ]
+  %tmp10 = add nsw i64 %arg, -1
+  %tmp11 = icmp slt i64 1, %tmp10
+  br i1 %tmp11, label %bb12, label %bb43
+
+bb12:                                             ; preds = %bb8
+  br label %bb13
+
+bb13:                                             ; preds = %bb39, %bb12
+  %tmp14 = phi i64 [ 1, %bb12 ], [ %tmp40, %bb39 ]
+  %tmp15 = icmp slt i64 0, %arg
+  br i1 %tmp15, label %bb16, label %bb23
+
+bb16:                                             ; preds = %bb13
+  br label %bb17
+
+bb17:                                             ; preds = %bb19, %bb16
+  %tmp18 = phi i64 [ 0, %bb16 ], [ %tmp20, %bb19 ]
+  br label %bb19
+
+bb19:                                             ; preds = %bb17
+  %tmp20 = add nuw nsw i64 %tmp18, 1
+  %tmp21 = icmp slt i64 %tmp20, %arg
+  br i1 %tmp21, label %bb17, label %bb22
+
+bb22:                                             ; preds = %bb19
+  br label %bb23
+
+bb23:                                             ; preds = %bb22, %bb13
+  %tmp24 = phi i64 [ %tmp14, %bb22 ], [ %tmp14, %bb13 ]
+  %tmp25 = icmp slt i64 0, %arg
+  br i1 %tmp25, label %bb26, label %bb37
+
+bb26:                                             ; preds = %bb23
+  br label %bb27
+
+bb27:                                             ; preds = %bb33, %bb26
+  %tmp28 = phi i64 [ 0, %bb26 ], [ %tmp34, %bb33 ]
+  %tmp29 = mul nsw i64 %tmp9, %arg
+  %tmp30 = getelementptr inbounds i32, i32* %arg1, i64 %tmp24
+  %tmp31 = getelementptr inbounds i32, i32* %tmp30, i64 %tmp29
+  %tmp32 = load i32, i32* %tmp31, align 4
+  br label %bb33
+
+bb33:                                             ; preds = %bb27
+  %tmp34 = add nuw nsw i64 %tmp28, 1
+  %tmp35 = icmp slt i64 %tmp34, %arg
+  br i1 %tmp35, label %bb27, label %bb36
+
+bb36:                                             ; preds = %bb33
+  br label %bb37
+
+bb37:                                             ; preds = %bb36, %bb23
+  %tmp38 = phi i64 [ %tmp24, %bb36 ], [ %tmp24, %bb23 ]
+  br label %bb39
+
+bb39:                                             ; preds = %bb37
+  %tmp40 = add nuw nsw i64 %tmp38, 1
+  %tmp41 = icmp slt i64 %tmp40, %tmp10
+  br i1 %tmp41, label %bb13, label %bb42
+
+bb42:                                             ; preds = %bb39
+  br label %bb43
+
+bb43:                                             ; preds = %bb42, %bb8
+  br label %bb44
+
+bb44:                                             ; preds = %bb43
+  %tmp45 = add nuw nsw i64 %tmp9, 1
+  %tmp46 = icmp slt i64 %tmp45, %arg
+  br i1 %tmp46, label %bb8, label %bb47
+
+bb47:                                             ; preds = %bb44
+  br label %bb48
+
+bb48:                                             ; preds = %bb47, %bb
+  ret void
+}
+
+; CHECK-LABEL @test3
+
+; CHECK:      %tmp14 = phi i64 [ %tmp40, %bb39 ], [ 1, %bb8 ]
+; CHECK-NEXT: -->  {1,+,1}<%bb13> U: [1,9223372036854775807) S: [1,9223372036854775807)
+; CHECK-SAME:      Exits: (-2 + %arg)       LoopDispositions: { %bb13: Computable, %bb8: Variant, %bb17_a: Invariant, %bb27: Invariant }
+; CHECK:      %tmp18 = phi i64 [ %tmp20, %bb17 ], [ 0, %bb13 ]
+; CHECK-NEXT: -->  {0,+,1}<nuw><nsw><%bb17_a> U: [0,9223372036854775807) S: [0,9223372036854775807)
+; CHECK-SAME:      Exits: (-1 + %arg)       LoopDispositions: { %bb17_a: Computable, %bb13: Variant, %bb8: Variant }
+
+; CHECK:      %tmp24 = phi i64 [ %tmp14, %bb13 ], [ %tmp14, %bb17 ]
+; CHECK-NEXT: -->  {1,+,1}<%bb13> U: [1,9223372036854775807) S: [1,9223372036854775807)
+; CHECK-SAME:      Exits: (-2 + %arg)       LoopDispositions: { %bb13: Computable, %bb8: Variant, %bb17_a: Invariant, %bb27: Invariant }
+; CHECK:       %tmp28 = phi i64 [ %tmp34, %bb27 ], [ 0, %bb23 ]
+; CHECK-NEXT:  -->  {0,+,1}<nuw><nsw><%bb27> U: [0,9223372036854775807) S: [0,9223372036854775807)
+; CHECK-SAME:       Exits: (-1 + %arg)      LoopDispositions: { %bb27: Computable, %bb13: Variant, %bb8: Variant }
+
+; CHECK:      %tmp38 = phi i64 [ %tmp24, %bb23 ], [ %tmp24, %bb27 ]
+; CHECK-NEXT: -->  {1,+,1}<%bb13> U: [1,9223372036854775807) S: [1,9223372036854775807)
+; CHECK-SAME:      Exits: (-2 + %arg)       LoopDispositions: { %bb13: Computable, %bb8: Variant, %bb17_a: Invariant, %bb27: Invariant }
+
+define void @test3(i64 %arg, i32* %arg1) {
+bb:
+  %tmp = icmp slt i64 0, %arg
+  br i1 %tmp, label %bb8, label %bb48
+
+bb8:                                              ; preds = %bb, %bb44
+  %tmp9 = phi i64 [ %tmp45, %bb44 ], [ 0, %bb ]
+  %tmp10 = add nsw i64 %arg, -1
+  %tmp11 = icmp slt i64 1, %tmp10
+  br i1 %tmp11, label %bb13, label %bb44
+
+bb13:                                             ; preds = %bb8, %bb39
+  %tmp14 = phi i64 [ %tmp40, %bb39 ], [ 1, %bb8 ]
+  %tmp15 = icmp slt i64 0, %arg
+  br i1 %tmp15, label %bb17_a, label %bb23
+
+bb17_a:
+  %tmp18 = phi i64 [ %tmp20, %bb17 ], [ 0, %bb13 ]
+  %tmp20 = add nuw nsw i64 %tmp18, 1
+
+  br label %bb17
+
+bb17:                                             ; preds = %bb13, %bb17
+  %tmp21 = icmp slt i64 %tmp20, %arg
+  br i1 %tmp21, label %bb17_a, label %bb23
+
+bb23:                                             ; preds = %bb17, %bb13
+  %tmp24 = phi i64 [ %tmp14, %bb13 ], [ %tmp14, %bb17 ]
+  %tmp25 = icmp slt i64 0, %arg
+  br i1 %tmp25, label %bb27, label %bb39
+
+bb27:                                             ; preds = %bb23, %bb27
+  %tmp28 = phi i64 [ %tmp34, %bb27 ], [ 0, %bb23 ]
+  %tmp29 = mul nsw i64 %tmp9, %arg
+  %tmp30 = getelementptr inbounds i32, i32* %arg1, i64 %tmp24
+  %tmp31 = getelementptr inbounds i32, i32* %tmp30, i64 %tmp29
+  %tmp32 = load i32, i32* %tmp31, align 4
+  %tmp34 = add nuw nsw i64 %tmp28, 1
+  %tmp35 = icmp slt i64 %tmp34, %arg
+  br i1 %tmp35, label %bb27, label %bb39
+
+bb39:                                             ; preds = %bb23, %bb27
+  %tmp38 = phi i64 [ %tmp24, %bb23 ], [ %tmp24, %bb27 ]
+  %tmp40 = add nuw nsw i64 %tmp38, 1
+  %tmp41 = icmp slt i64 %tmp40, %tmp10
+  br i1 %tmp41, label %bb13, label %bb44
+
+bb44:                                             ; preds = %bb8, %bb39
+  %tmp45 = add nuw nsw i64 %tmp9, 1
+  %tmp46 = icmp slt i64 %tmp45, %arg
+  br i1 %tmp46, label %bb8, label %bb48
+
+bb48:                                             ; preds = %bb44, %bb
+  ret void
+}
diff --git a/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll b/llvm/test/Transforms/IndVarSimplify/scev-expander-preserve-lcssa.ll
new file mode 100644 (file)
index 0000000..d26d3b2
--- /dev/null
@@ -0,0 +1,587 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -indvars -S -indvars -verify-loop-lcssa %s | FileCheck %s
+
+; Make sure SCEVExpander does not crash and introduce unnecessary LCSSA PHI nodes.
+; The tests are a collection of cases with crashes when preserving LCSSA PHI
+; nodes directly in SCEVExpander.
+
+declare i1 @cond() readnone
+
+define void @test1(i8 %x, [512 x i8]* %ptr) {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[LAND_LHS_TRUE:%.*]]
+; CHECK:       land.lhs.true:
+; CHECK-NEXT:    br label [[WHILE_COND22:%.*]]
+; CHECK:       while.cond22:
+; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_1]], label [[WHILE_COND22]], label [[WHILE_COND29_PREHEADER:%.*]]
+; CHECK:       while.cond29.preheader:
+; CHECK-NEXT:    br label [[WHILE_BODY35:%.*]]
+; CHECK:       while.body35:
+; CHECK-NEXT:    [[I_1107:%.*]] = phi i32 [ [[I_9:%.*]], [[IF_END224:%.*]] ], [ 0, [[WHILE_COND29_PREHEADER]] ]
+; CHECK-NEXT:    br label [[WHILE_COND192:%.*]]
+; CHECK:       while.cond192:
+; CHECK-NEXT:    switch i8 [[X:%.*]], label [[WHILE_BODY205:%.*]] [
+; CHECK-NEXT:    i8 59, label [[WHILE_COND215_PREHEADER:%.*]]
+; CHECK-NEXT:    i8 10, label [[IF_END224_LOOPEXIT1:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       while.cond215.preheader:
+; CHECK-NEXT:    br label [[WHILE_COND215:%.*]]
+; CHECK:       while.body205:
+; CHECK-NEXT:    br label [[WHILE_COND192]]
+; CHECK:       while.cond215:
+; CHECK-NEXT:    [[I_8_IN:%.*]] = phi i32 [ [[I_8:%.*]], [[WHILE_COND215]] ], [ [[I_1107]], [[WHILE_COND215_PREHEADER]] ]
+; CHECK-NEXT:    [[I_8]] = add nsw i32 [[I_8_IN]], 1
+; CHECK-NEXT:    [[IDXPROM216:%.*]] = sext i32 [[I_8]] to i64
+; CHECK-NEXT:    [[ARRAYIDX217:%.*]] = getelementptr inbounds [512 x i8], [512 x i8]* [[PTR:%.*]], i64 0, i64 [[IDXPROM216]]
+; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_2]], label [[WHILE_COND215]], label [[IF_END224_LOOPEXIT:%.*]]
+; CHECK:       if.end224.loopexit:
+; CHECK-NEXT:    [[I_8_LCSSA:%.*]] = phi i32 [ [[I_8]], [[WHILE_COND215]] ]
+; CHECK-NEXT:    br label [[IF_END224]]
+; CHECK:       if.end224.loopexit1:
+; CHECK-NEXT:    br label [[IF_END224]]
+; CHECK:       if.end224:
+; CHECK-NEXT:    [[I_9]] = phi i32 [ [[I_8_LCSSA]], [[IF_END224_LOOPEXIT]] ], [ [[I_1107]], [[IF_END224_LOOPEXIT1]] ]
+; CHECK-NEXT:    [[C_3:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_3]], label [[WHILE_END225:%.*]], label [[WHILE_BODY35]]
+; CHECK:       while.end225:
+; CHECK-NEXT:    br label [[LAND_LHS_TRUE]]
+;
+entry:
+  br label %land.lhs.true
+
+land.lhs.true:                                    ; preds = %while.end225, %entry
+  br label %while.cond22
+
+while.cond22:                                     ; preds = %while.cond22, %land.lhs.true
+  %c.1 = call i1 @cond()
+  br i1 %c.1, label %while.cond22, label %while.cond29.preheader
+
+while.cond29.preheader:                           ; preds = %while.cond22
+  br label %while.body35
+
+while.body35:                                     ; preds = %if.end224, %while.cond29.preheader
+  %i.1107 = phi i32 [ %i.9, %if.end224 ], [ 0, %while.cond29.preheader ]
+  br label %while.cond192
+
+while.cond192:                                    ; preds = %while.body205, %while.body35
+  %i.7 = phi i32 [ %i.1107, %while.body35 ], [ %inc206, %while.body205 ]
+  switch i8 %x, label %while.body205 [
+  i8 59, label %while.cond215
+  i8 10, label %if.end224
+  ]
+
+while.body205:                                    ; preds = %while.cond192
+  %inc206 = add nsw i32 %i.7, 1
+  br label %while.cond192
+
+while.cond215:                                    ; preds = %while.cond215, %while.cond192
+  %i.8.in = phi i32 [ %i.8, %while.cond215 ], [ %i.7, %while.cond192 ]
+  %i.8 = add nsw i32 %i.8.in, 1
+  %idxprom216 = sext i32 %i.8 to i64
+  %arrayidx217 = getelementptr inbounds [512 x i8], [512 x i8]* %ptr, i64 0, i64 %idxprom216
+  %c.2 = call i1 @cond()
+  br i1 %c.2, label %while.cond215, label %if.end224
+
+if.end224:                                        ; preds = %while.cond215, %while.cond192
+  %i.9 = phi i32 [ %i.8, %while.cond215 ], [ %i.7, %while.cond192 ]
+  %c.3 = call i1 @cond()
+  br i1 %c.3, label %while.end225, label %while.body35
+
+while.end225:                                     ; preds = %if.end224
+  br label %land.lhs.true
+}
+
+define void @test2(i16 %x)  {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_1]], label [[FOR_COND_PREHEADER:%.*]], label [[RETURN:%.*]]
+; CHECK:       for.cond.preheader:
+; CHECK-NEXT:    br label [[FOR_COND:%.*]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    switch i16 [[X:%.*]], label [[RETURN_LOOPEXIT1:%.*]] [
+; CHECK-NEXT:    i16 41, label [[FOR_END:%.*]]
+; CHECK-NEXT:    i16 43, label [[FOR_COND]]
+; CHECK-NEXT:    ]
+; CHECK:       for.end:
+; CHECK-NEXT:    [[I_0_LCSSA2:%.*]] = phi i32 [ 0, [[FOR_COND]] ]
+; CHECK-NEXT:    [[CMP8243:%.*]] = icmp sgt i32 [[I_0_LCSSA2]], 0
+; CHECK-NEXT:    br i1 [[CMP8243]], label [[FOR_BODY84_PREHEADER:%.*]], label [[RETURN]]
+; CHECK:       for.body84.preheader:
+; CHECK-NEXT:    br label [[FOR_BODY84:%.*]]
+; CHECK:       for.body84:
+; CHECK-NEXT:    [[I_144:%.*]] = phi i32 [ [[INC:%.*]], [[IF_END106:%.*]] ], [ 0, [[FOR_BODY84_PREHEADER]] ]
+; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_2]], label [[IF_END106]], label [[RETURN_LOOPEXIT:%.*]]
+; CHECK:       if.end106:
+; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[I_144]], 1
+; CHECK-NEXT:    [[CMP82:%.*]] = icmp slt i32 [[INC]], [[I_0_LCSSA2]]
+; CHECK-NEXT:    br i1 [[CMP82]], label [[FOR_BODY84]], label [[RETURN_LOOPEXIT]]
+; CHECK:       return.loopexit:
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return.loopexit1:
+; CHECK-NEXT:    br label [[RETURN]]
+; CHECK:       return:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %c.1 = call i1 @cond()
+  br i1 %c.1, label %for.cond, label %return
+
+for.cond:                                         ; preds = %for.cond, %entry
+  %i.0 = phi i32 [ %sub, %for.cond ], [ 0, %entry ]
+  %sub = add nsw i32 %i.0, -1
+  switch i16 %x, label %return [
+  i16 41, label %for.end
+  i16 43, label %for.cond
+  ]
+
+for.end:                                          ; preds = %for.cond
+  %cmp8243 = icmp sgt i32 %i.0, 0
+  br i1 %cmp8243, label %for.body84, label %return
+
+for.body84:                                       ; preds = %if.end106, %for.end
+  %i.144 = phi i32 [ %inc, %if.end106 ], [ 0, %for.end ]
+  %c.2 = call i1 @cond()
+  br i1 %c.2, label %if.end106, label %return
+
+if.end106:                                        ; preds = %for.body84
+  %inc = add nuw nsw i32 %i.144, 1
+  %cmp82 = icmp slt i32 %inc, %i.0
+  br i1 %cmp82, label %for.body84, label %return
+
+return:                                           ; preds = %if.end106, %for.body84, %for.end, %for.cond, %entry
+  ret void
+}
+
+declare i32 @get.i32() readnone
+
+define void @test3(i32* %ptr) {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
+; CHECK:       while.body:
+; CHECK-NEXT:    br label [[FOR_BODY1208:%.*]]
+; CHECK:       for.body1208:
+; CHECK-NEXT:    [[M_0804:%.*]] = phi i32 [ 1, [[WHILE_BODY]] ], [ [[INC1499:%.*]], [[FOR_INC1498:%.*]] ]
+; CHECK-NEXT:    [[V:%.*]] = call i32 @get.i32()
+; CHECK-NEXT:    [[CMP1358:%.*]] = icmp eq i32 [[V]], 0
+; CHECK-NEXT:    br i1 [[CMP1358]], label [[IF_THEN1360:%.*]], label [[FOR_INC1498]]
+; CHECK:       if.then1360:
+; CHECK-NEXT:    [[M_0804_LCSSA:%.*]] = phi i32 [ [[M_0804]], [[FOR_BODY1208]] ]
+; CHECK-NEXT:    br label [[FOR_COND1390:%.*]]
+; CHECK:       for.cond1390:
+; CHECK-NEXT:    [[M_2_IN:%.*]] = phi i32 [ [[M_0804_LCSSA]], [[IF_THEN1360]] ], [ 0, [[FOR_BODY1394:%.*]] ]
+; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_2]], label [[FOR_BODY1394]], label [[FOR_END1469:%.*]]
+; CHECK:       for.body1394:
+; CHECK-NEXT:    br label [[FOR_COND1390]]
+; CHECK:       for.end1469:
+; CHECK-NEXT:    [[M_2_IN_LCSSA:%.*]] = phi i32 [ [[M_2_IN]], [[FOR_COND1390]] ]
+; CHECK-NEXT:    store i32 [[M_2_IN_LCSSA]], i32* [[PTR:%.*]], align 4
+; CHECK-NEXT:    br label [[WHILE_BODY]]
+; CHECK:       for.inc1498:
+; CHECK-NEXT:    [[INC1499]] = add nuw nsw i32 [[M_0804]], 1
+; CHECK-NEXT:    br label [[FOR_BODY1208]]
+;
+entry:
+  br label %while.body
+
+while.body:                                       ; preds = %for.end1469, %entry
+  br label %for.body1208
+
+for.body1208:                                     ; preds = %for.inc1498, %while.body
+  %m.0804 = phi i32 [ 1, %while.body ], [ %inc1499, %for.inc1498 ]
+  %v = call i32 @get.i32()
+  %cmp1358 = icmp eq i32 %v, 0
+  br i1 %cmp1358, label %if.then1360, label %for.inc1498
+
+if.then1360:                                      ; preds = %for.body1208
+  br label %for.cond1390
+
+for.cond1390:                                     ; preds = %for.body1394, %if.then1360
+  %m.2.in = phi i32 [ %m.0804, %if.then1360 ], [ 0, %for.body1394 ]
+  %c.2 = call i1 @cond()
+  br i1 %c.2, label %for.body1394, label %for.end1469
+
+for.body1394:                                     ; preds = %for.cond1390
+  br label %for.cond1390
+
+for.end1469:                                      ; preds = %for.cond1390
+  store i32 %m.2.in, i32* %ptr, align 4
+  br label %while.body
+
+for.inc1498:                                      ; preds = %for.body1208
+  %inc1499 = add nuw nsw i32 %m.0804, 1
+  br label %for.body1208
+}
+
+define void @test4(i32* %ptr) {
+; CHECK-LABEL: @test4(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
+; CHECK:       while.body:
+; CHECK-NEXT:    br label [[FOR_COND1204_PREHEADER:%.*]]
+; CHECK:       for.cond1204.preheader:
+; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_1]], label [[IF_THEN1504:%.*]], label [[FOR_BODY1208_LR_PH:%.*]]
+; CHECK:       for.body1208.lr.ph:
+; CHECK-NEXT:    br label [[FOR_BODY1208:%.*]]
+; CHECK:       for.body1208:
+; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[FOR_BODY1208_LR_PH]] ], [ [[TMP1:%.*]], [[FOR_INC1498:%.*]] ]
+; CHECK-NEXT:    [[M_0804:%.*]] = phi i32 [ 1, [[FOR_BODY1208_LR_PH]] ], [ [[INC1499:%.*]], [[FOR_INC1498]] ]
+; CHECK-NEXT:    [[IDXPROM1212:%.*]] = zext i32 [[M_0804]] to i64
+; CHECK-NEXT:    [[V:%.*]] = call i32 @get.i32()
+; CHECK-NEXT:    [[CMP1215:%.*]] = icmp eq i32 0, [[V]]
+; CHECK-NEXT:    [[YPOS1223:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 [[IDXPROM1212]]
+; CHECK-NEXT:    br i1 [[CMP1215]], label [[IF_THEN1217:%.*]], label [[IF_ELSE1351:%.*]]
+; CHECK:       if.then1217:
+; CHECK-NEXT:    [[M_0804_LCSSA:%.*]] = phi i32 [ [[M_0804]], [[FOR_BODY1208]] ]
+; CHECK-NEXT:    br label [[FOR_COND1247:%.*]]
+; CHECK:       for.cond1247:
+; CHECK-NEXT:    [[M_1_IN:%.*]] = phi i32 [ [[M_0804_LCSSA]], [[IF_THEN1217]] ], [ [[M_1:%.*]], [[IF_THEN1260:%.*]] ]
+; CHECK-NEXT:    [[M_1]] = add nuw nsw i32 [[M_1_IN]], 1
+; CHECK-NEXT:    br label [[FOR_BODY1251:%.*]]
+; CHECK:       for.body1251:
+; CHECK-NEXT:    [[IDXPROM1255:%.*]] = zext i32 [[M_1]] to i64
+; CHECK-NEXT:    [[XPOS1257:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i64 [[IDXPROM1255]]
+; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_2]], label [[IF_THEN1260]], label [[FOR_END1326:%.*]]
+; CHECK:       if.then1260:
+; CHECK-NEXT:    br label [[FOR_COND1247]]
+; CHECK:       for.end1326:
+; CHECK-NEXT:    br label [[IF_END1824:%.*]]
+; CHECK:       if.else1351:
+; CHECK-NEXT:    [[V_2:%.*]] = call i32 @get.i32()
+; CHECK-NEXT:    [[CMP1358:%.*]] = icmp eq i32 [[V_2]], 0
+; CHECK-NEXT:    br i1 [[CMP1358]], label [[IF_THEN1360:%.*]], label [[FOR_INC1498]]
+; CHECK:       if.then1360:
+; CHECK-NEXT:    [[DOTLCSSA2:%.*]] = phi i32 [ [[TMP0]], [[IF_ELSE1351]] ]
+; CHECK-NEXT:    [[M_0804_LCSSA1:%.*]] = phi i32 [ [[M_0804]], [[IF_ELSE1351]] ]
+; CHECK-NEXT:    [[CMP1392:%.*]] = icmp slt i32 [[M_0804_LCSSA1]], [[DOTLCSSA2]]
+; CHECK-NEXT:    unreachable
+; CHECK:       for.inc1498:
+; CHECK-NEXT:    [[INC1499]] = add nuw nsw i32 [[M_0804]], 1
+; CHECK-NEXT:    [[TMP1]] = load i32, i32* [[PTR]], align 8
+; CHECK-NEXT:    br label [[FOR_BODY1208]]
+; CHECK:       if.then1504:
+; CHECK-NEXT:    unreachable
+; CHECK:       if.end1824:
+; CHECK-NEXT:    br label [[WHILE_BODY]]
+;
+entry:
+  br label %while.body
+
+while.body:                                       ; preds = %if.end1824, %entry
+  br label %for.cond1204.preheader
+
+for.cond1204.preheader:                           ; preds = %while.body
+  %c.1 = call i1 @cond()
+  br i1 %c.1, label %if.then1504, label %for.body1208.lr.ph
+
+for.body1208.lr.ph:                               ; preds = %for.cond1204.preheader
+  br label %for.body1208
+
+for.body1208:                                     ; preds = %for.inc1498, %for.body1208.lr.ph
+  %0 = phi i32 [ 0, %for.body1208.lr.ph ], [ %1, %for.inc1498 ]
+  %m.0804 = phi i32 [ 1, %for.body1208.lr.ph ], [ %inc1499, %for.inc1498 ]
+  %idxprom1212 = zext i32 %m.0804 to i64
+  %v = call i32 @get.i32()
+  %cmp1215 = icmp eq i32 0, %v
+  %ypos1223 = getelementptr inbounds i32, i32* %ptr , i64 %idxprom1212
+  br i1 %cmp1215, label %if.then1217, label %if.else1351
+
+if.then1217:                                      ; preds = %for.body1208
+  br label %for.cond1247
+
+for.cond1247:                                     ; preds = %if.then1260, %if.then1217
+  %m.1.in = phi i32 [ %m.0804, %if.then1217 ], [ %m.1, %if.then1260 ]
+  %m.1 = add nuw nsw i32 %m.1.in, 1
+  %cmp1249 = icmp slt i32 %m.1.in, %0
+  br label %for.body1251
+
+for.body1251:                                     ; preds = %for.cond1247
+  %idxprom1255 = zext i32 %m.1 to i64
+  %xpos1257 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom1255
+  %c.2 = call i1 @cond()
+  br i1 %c.2, label %if.then1260, label %for.end1326
+
+if.then1260:                                      ; preds = %for.body1251
+  br label %for.cond1247
+
+for.end1326:                                      ; preds = %for.body1251
+  br label %if.end1824
+
+if.else1351:                                      ; preds = %for.body1208
+  %v.2 = call i32 @get.i32()
+  %cmp1358 = icmp eq i32 %v.2, 0
+  br i1 %cmp1358, label %if.then1360, label %for.inc1498
+
+if.then1360:                                      ; preds = %if.else1351
+  %cmp1392 = icmp slt i32 %m.0804, %0
+  unreachable
+
+for.inc1498:                                      ; preds = %if.else1351
+  %inc1499 = add nuw nsw i32 %m.0804, 1
+  %1 = load i32, i32* %ptr, align 8
+  br label %for.body1208
+
+if.then1504:                                      ; preds = %for.cond1204.preheader
+  unreachable
+
+if.end1824:                                       ; preds = %for.end1326
+  br label %while.body
+}
+
+define void @test5(i8* %header, i32 %conv, i8 %n) {
+; CHECK-LABEL: @test5(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[POS_42:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[ADD85:%.*]], [[FOR_INC:%.*]] ]
+; CHECK-NEXT:    br label [[FOR_INNER:%.*]]
+; CHECK:       for.inner:
+; CHECK-NEXT:    [[I_0_I:%.*]] = phi i32 [ 0, [[FOR_BODY]] ], [ [[INC_I:%.*]], [[FOR_INNER]] ]
+; CHECK-NEXT:    [[INC_I]] = add nuw nsw i32 [[I_0_I]], 1
+; CHECK-NEXT:    [[CMP7_I:%.*]] = icmp slt i8 [[N:%.*]], 0
+; CHECK-NEXT:    br i1 [[CMP7_I]], label [[FOR_INNER]], label [[FOR_INNER_EXIT:%.*]]
+; CHECK:       for.inner.exit:
+; CHECK-NEXT:    [[INC_I_LCSSA:%.*]] = phi i32 [ [[INC_I]], [[FOR_INNER]] ]
+; CHECK-NEXT:    br label [[FOR_INNER_2:%.*]]
+; CHECK:       for.inner.2:
+; CHECK-NEXT:    [[I_0_I1:%.*]] = phi i32 [ 0, [[FOR_INNER_EXIT]] ], [ [[INC_I3:%.*]], [[FOR_INNER_2]] ]
+; CHECK-NEXT:    [[INC_I3]] = add nuw nsw i32 [[I_0_I1]], 1
+; CHECK-NEXT:    [[CMP7_I4:%.*]] = icmp slt i8 [[N]], 0
+; CHECK-NEXT:    br i1 [[CMP7_I4]], label [[FOR_INNER_2]], label [[FOR_INC]]
+; CHECK:       for.inc:
+; CHECK-NEXT:    [[INC_I3_LCSSA:%.*]] = phi i32 [ [[INC_I3]], [[FOR_INNER_2]] ]
+; CHECK-NEXT:    [[ADD71:%.*]] = add i32 [[POS_42]], [[INC_I_LCSSA]]
+; CHECK-NEXT:    [[ADD85]] = add i32 [[ADD71]], [[INC_I3_LCSSA]]
+; CHECK-NEXT:    br i1 false, label [[FOR_BODY]], label [[WHILE_COND_PREHEADER:%.*]]
+; CHECK:       while.cond.preheader:
+; CHECK-NEXT:    [[ADD85_LCSSA:%.*]] = phi i32 [ [[ADD85]], [[FOR_INC]] ]
+; CHECK-NEXT:    [[SHL:%.*]] = shl nuw nsw i32 [[CONV:%.*]], 2
+; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
+; CHECK:       while.cond:
+; CHECK-NEXT:    [[POS_8:%.*]] = phi i32 [ [[INC114:%.*]], [[WHILE_BODY:%.*]] ], [ [[ADD85_LCSSA]], [[WHILE_COND_PREHEADER]] ]
+; CHECK-NEXT:    [[CMP112:%.*]] = icmp ult i32 [[POS_8]], [[SHL]]
+; CHECK-NEXT:    br i1 [[CMP112]], label [[WHILE_BODY]], label [[CLEANUP122:%.*]]
+; CHECK:       while.body:
+; CHECK-NEXT:    [[INC114]] = add nuw i32 [[POS_8]], 1
+; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_1]], label [[WHILE_COND]], label [[CLEANUP122]]
+; CHECK:       cleanup122:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %shl = shl nuw nsw i32 %conv, 2
+  br label %for.body
+
+for.body:                                         ; preds = %entry, %for.inc
+  %pos.42 = phi i32 [ 0, %entry ], [ %add85, %for.inc ]
+  br label %for.inner
+
+for.inner:                                       ; preds = %for.body.i, %for.body
+  %i.0.i = phi i32 [ 0, %for.body ], [ %inc.i, %for.inner ]
+  %inc.i = add nuw nsw i32 %i.0.i, 1
+  %cmp7.i = icmp slt i8 %n, 0
+  br i1 %cmp7.i, label %for.inner, label %for.inner.exit
+
+for.inner.exit:                                   ; preds = %for.body.i
+  %add71 = add i32 %pos.42, %inc.i
+  br label %for.inner.2
+
+for.inner.2:                                      ; preds = %for.body.i6, %cleanup.cont74
+  %i.0.i1 = phi i32 [ 0, %for.inner.exit ], [ %inc.i3, %for.inner.2]
+  %inc.i3 = add nuw nsw i32 %i.0.i1, 1
+  %cmp7.i4 = icmp slt i8 %n, 0
+  br i1 %cmp7.i4, label %for.inner.2, label %for.inc
+
+for.inc:                                          ; preds = %for.body.i6
+  %add85 = add i32 %add71, %inc.i3
+  br i1 false, label %for.body, label %while.cond.preheader
+
+while.cond.preheader:                             ; preds = %for.inc
+  br label %while.cond
+
+while.cond:                                       ; preds = %while.cond.preheader, %while.body
+  %pos.8 = phi i32 [ %inc114, %while.body ], [ %add85, %while.cond.preheader ]
+  %cmp112 = icmp ult i32 %pos.8, %shl
+  br i1 %cmp112, label %while.body, label %cleanup122
+
+while.body:                                       ; preds = %while.cond
+  %inc114 = add nuw i32 %pos.8, 1
+  %c.1 = call i1 @cond()
+  br i1 %c.1, label %while.cond, label %cleanup122
+
+cleanup122:                                       ; preds = %while.body, %while.cond
+  ret void
+}
+
+define void @test6(i8 %x) {
+; CHECK-LABEL: @test6(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_1]], label [[LAND_RHS:%.*]], label [[WHILE_END316:%.*]]
+; CHECK:       land.rhs:
+; CHECK-NEXT:    br label [[WHILE_BODY35:%.*]]
+; CHECK:       while.body35:
+; CHECK-NEXT:    br label [[WHILE_COND192:%.*]]
+; CHECK:       while.cond192:
+; CHECK-NEXT:    switch i8 [[X:%.*]], label [[WHILE_BODY205:%.*]] [
+; CHECK-NEXT:    i8 59, label [[WHILE_COND215_PREHEADER:%.*]]
+; CHECK-NEXT:    i8 10, label [[IF_END224:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       while.cond215.preheader:
+; CHECK-NEXT:    [[I_7_LCSSA:%.*]] = phi i32 [ 0, [[WHILE_COND192]] ]
+; CHECK-NEXT:    br label [[WHILE_COND215:%.*]]
+; CHECK:       while.body205:
+; CHECK-NEXT:    br label [[WHILE_COND192]]
+; CHECK:       while.cond215:
+; CHECK-NEXT:    [[I_8_IN:%.*]] = phi i32 [ [[I_8:%.*]], [[WHILE_COND215]] ], [ [[I_7_LCSSA]], [[WHILE_COND215_PREHEADER]] ]
+; CHECK-NEXT:    [[I_8]] = add nuw nsw i32 [[I_8_IN]], 1
+; CHECK-NEXT:    [[IDXPROM216:%.*]] = sext i32 [[I_8]] to i64
+; CHECK-NEXT:    [[ARRAYIDX217:%.*]] = getelementptr inbounds [512 x i8], [512 x i8]* null, i64 0, i64 [[IDXPROM216]]
+; CHECK-NEXT:    br label [[WHILE_COND215]]
+; CHECK:       if.end224:
+; CHECK-NEXT:    [[C_2:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_2]], label [[WHILE_END225:%.*]], label [[WHILE_BODY35]]
+; CHECK:       while.end225:
+; CHECK-NEXT:    unreachable
+; CHECK:       while.end316:
+; CHECK-NEXT:    ret void
+;
+entry:
+  %c.1 = call i1 @cond()
+  br i1 %c.1, label %land.rhs, label %while.end316
+
+land.rhs:                                         ; preds = %entry
+  br label %while.body35
+
+while.body35:                                     ; preds = %if.end224, %land.rhs
+  br label %while.cond192
+
+while.cond192:                                    ; preds = %while.body205, %while.body35
+  %i.7 = phi i32 [ 0, %while.body35 ], [ %inc206, %while.body205 ]
+  switch i8 %x, label %while.body205 [
+  i8 59, label %while.cond215
+  i8 10, label %if.end224
+  ]
+
+while.body205:                                    ; preds = %while.cond192
+  %inc206 = add nsw i32 %i.7, 1
+  br label %while.cond192
+
+while.cond215:                                    ; preds = %while.cond215, %while.cond192
+  %i.8.in = phi i32 [ %i.8, %while.cond215 ], [ %i.7, %while.cond192 ]
+  %i.8 = add nsw i32 %i.8.in, 1
+  %idxprom216 = sext i32 %i.8 to i64
+  %arrayidx217 = getelementptr inbounds [512 x i8], [512 x i8]* null, i64 0, i64 %idxprom216
+  br label %while.cond215
+
+if.end224:                                        ; preds = %while.cond192
+  %c.2 = call i1 @cond()
+  br i1 %c.2, label %while.end225, label %while.body35
+
+while.end225:                                     ; preds = %if.end224
+  unreachable
+
+while.end316:                                     ; preds = %entry
+  ret void
+}
+
+define void @test7(i32* %ptr) {
+; CHECK-LABEL: @test7(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[WHILE_BODY:%.*]]
+; CHECK:       while.body:
+; CHECK-NEXT:    br label [[FOR_BODY1208:%.*]]
+; CHECK:       for.body1208:
+; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ undef, [[WHILE_BODY]] ], [ [[TMP1:%.*]], [[FOR_INC1498:%.*]] ]
+; CHECK-NEXT:    [[M_048:%.*]] = phi i32 [ 1, [[WHILE_BODY]] ], [ [[INC1499:%.*]], [[FOR_INC1498]] ]
+; CHECK-NEXT:    [[IDXPROM1212:%.*]] = zext i32 [[M_048]] to i64
+; CHECK-NEXT:    [[XPOS1214:%.*]] = getelementptr inbounds i32, i32* [[PTR:%.*]], i64 [[IDXPROM1212]]
+; CHECK-NEXT:    [[V_1:%.*]] = call i32 @get.i32()
+; CHECK-NEXT:    [[CMP1215:%.*]] = icmp eq i32 0, [[V_1]]
+; CHECK-NEXT:    br i1 [[CMP1215]], label [[IF_THEN1217:%.*]], label [[IF_ELSE1351:%.*]]
+; CHECK:       if.then1217:
+; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi i32 [ [[TMP0]], [[FOR_BODY1208]] ]
+; CHECK-NEXT:    [[M_048_LCSSA:%.*]] = phi i32 [ [[M_048]], [[FOR_BODY1208]] ]
+; CHECK-NEXT:    [[CMP1249_NOT_NOT:%.*]] = icmp slt i32 [[M_048_LCSSA]], [[DOTLCSSA]]
+; CHECK-NEXT:    unreachable
+; CHECK:       if.else1351:
+; CHECK-NEXT:    [[CMP1358:%.*]] = icmp eq i32 0, undef
+; CHECK-NEXT:    br i1 [[CMP1358]], label [[IF_THEN1360:%.*]], label [[FOR_INC1498]]
+; CHECK:       if.then1360:
+; CHECK-NEXT:    [[M_048_LCSSA1:%.*]] = phi i32 [ [[M_048]], [[IF_ELSE1351]] ]
+; CHECK-NEXT:    br label [[FOR_COND1390:%.*]]
+; CHECK:       for.cond1390:
+; CHECK-NEXT:    [[M_2_IN:%.*]] = phi i32 [ [[M_048_LCSSA1]], [[IF_THEN1360]] ], [ [[M_2:%.*]], [[IF_THEN1403:%.*]] ]
+; CHECK-NEXT:    [[M_2]] = add nuw nsw i32 [[M_2_IN]], 1
+; CHECK-NEXT:    [[IDXPROM1398:%.*]] = zext i32 [[M_2]] to i64
+; CHECK-NEXT:    br label [[IF_THEN1403]]
+; CHECK:       if.then1403:
+; CHECK-NEXT:    [[XPOS1409:%.*]] = getelementptr inbounds i32, i32* [[PTR]], i64 [[IDXPROM1398]]
+; CHECK-NEXT:    [[C_1:%.*]] = call i1 @cond()
+; CHECK-NEXT:    br i1 [[C_1]], label [[FOR_COND1390]], label [[FOR_END1469:%.*]]
+; CHECK:       for.end1469:
+; CHECK-NEXT:    br label [[IF_END1824:%.*]]
+; CHECK:       for.inc1498:
+; CHECK-NEXT:    [[INC1499]] = add nuw nsw i32 [[M_048]], 1
+; CHECK-NEXT:    [[TMP1]] = load i32, i32* undef, align 8
+; CHECK-NEXT:    br label [[FOR_BODY1208]]
+; CHECK:       if.end1824:
+; CHECK-NEXT:    br label [[WHILE_BODY]]
+;
+entry:
+  br label %while.body
+
+while.body:                                       ; preds = %if.end1824, %entry
+  br label %for.body1208
+
+for.body1208:                                     ; preds = %for.inc1498, %while.body
+  %0 = phi i32 [ undef, %while.body ], [ %1, %for.inc1498 ]
+  %m.048 = phi i32 [ 1, %while.body ], [ %inc1499, %for.inc1498 ]
+  %idxprom1212 = zext i32 %m.048 to i64
+  %xpos1214 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom1212
+  %v.1 = call i32 @get.i32()
+  %cmp1215 = icmp eq i32 0, %v.1
+  br i1 %cmp1215, label %if.then1217, label %if.else1351
+
+if.then1217:                                      ; preds = %for.body1208
+  %cmp1249.not.not = icmp slt i32 %m.048, %0
+  unreachable
+
+if.else1351:                                      ; preds = %for.body1208
+  %cmp1358 = icmp eq i32 0, undef
+  br i1 %cmp1358, label %if.then1360, label %for.inc1498
+
+if.then1360:                                      ; preds = %if.else1351
+  br label %for.cond1390
+
+for.cond1390:                                     ; preds = %if.then1403, %if.then1360
+  %m.2.in = phi i32 [ %m.048, %if.then1360 ], [ %m.2, %if.then1403 ]
+  %m.2 = add nuw nsw i32 %m.2.in, 1
+  %cmp1392.not.not = icmp slt i32 %m.2.in, %0
+  %idxprom1398 = zext i32 %m.2 to i64
+  br label %if.then1403
+
+if.then1403:                                      ; preds = %for.cond1390
+  %xpos1409 = getelementptr inbounds i32, i32* %ptr, i64 %idxprom1398
+  %c.1 = call i1 @cond()
+  br i1 %c.1, label %for.cond1390, label %for.end1469
+
+for.end1469:                                      ; preds = %if.then1403
+  br label %if.end1824
+
+for.inc1498:                                      ; preds = %if.else1351
+  %inc1499 = add nuw nsw i32 %m.048, 1
+  %1 = load i32, i32* undef, align 8
+  br label %for.body1208
+
+if.end1824:                                       ; preds = %for.end1469
+  br label %while.body
+}
index 1bee370..0f725a1 100644 (file)
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -loop-reduce -S | FileCheck %s
 
 target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
@@ -10,13 +11,42 @@ declare void @external(i32*)
 declare void @reserve()
 
 define void @f() personality i32 (...)* @_except_handler3 {
+; CHECK-LABEL: @f(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[THROW:%.*]]
+; CHECK:       throw:
+; CHECK-NEXT:    [[TMP96:%.*]] = getelementptr inbounds i8, i8* undef, i32 1
+; CHECK-NEXT:    invoke void @reserve()
+; CHECK-NEXT:    to label [[THROW]] unwind label [[PAD:%.*]]
+; CHECK:       pad:
+; CHECK-NEXT:    [[PHI2:%.*]] = phi i8* [ [[TMP96]], [[THROW]] ]
+; CHECK-NEXT:    [[CS:%.*]] = catchswitch within none [label %unreachable] unwind label [[BLAH2:%.*]]
+; CHECK:       unreachable:
+; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS]] []
+; CHECK-NEXT:    unreachable
+; CHECK:       blah2:
+; CHECK-NEXT:    [[CLEANUPPADI4_I_I_I:%.*]] = cleanuppad within none []
+; CHECK-NEXT:    [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 1, [[PHI21]]
+; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP1]]
+; CHECK-NEXT:    br label [[LOOP_BODY:%.*]]
+; CHECK:       loop_body:
+; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLAH2]] ]
+; CHECK-NEXT:    [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
+; CHECK-NEXT:    [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
+; CHECK-NEXT:    br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
+; CHECK:       iter:
+; CHECK-NEXT:    br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]
+; CHECK:       unwind_out:
+; CHECK-NEXT:    cleanupret from [[CLEANUPPADI4_I_I_I]] unwind to caller
+;
 entry:
   br label %throw
 
 throw:                                            ; preds = %throw, %entry
   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
   invoke void @reserve()
-          to label %throw unwind label %pad
+  to label %throw unwind label %pad
 
 pad:                                              ; preds = %throw
   %phi2 = phi i8* [ %tmp96, %throw ]
@@ -43,18 +73,45 @@ unwind_out:                                       ; preds = %iter, %loop_body
   cleanupret from %cleanuppadi4.i.i.i unwind to caller
 }
 
-; CHECK-LABEL: define void @f(
-; CHECK: cleanuppad within none []
-; CHECK-NEXT: ptrtoint i8* %phi2 to i32
-
 define void @g() personality i32 (...)* @_except_handler3 {
+; CHECK-LABEL: @g(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[THROW:%.*]]
+; CHECK:       throw:
+; CHECK-NEXT:    [[TMP96:%.*]] = getelementptr inbounds i8, i8* undef, i32 1
+; CHECK-NEXT:    invoke void @reserve()
+; CHECK-NEXT:    to label [[THROW]] unwind label [[PAD:%.*]]
+; CHECK:       pad:
+; CHECK-NEXT:    [[PHI2:%.*]] = phi i8* [ [[TMP96]], [[THROW]] ]
+; CHECK-NEXT:    [[CS:%.*]] = catchswitch within none [label [[UNREACHABLE:%.*]], label %blah] unwind to caller
+; CHECK:       unreachable:
+; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS]] []
+; CHECK-NEXT:    unreachable
+; CHECK:       blah:
+; CHECK-NEXT:    [[CATCHPAD:%.*]] = catchpad within [[CS]] []
+; CHECK-NEXT:    [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 1, [[PHI21]]
+; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP1]]
+; CHECK-NEXT:    br label [[LOOP_BODY:%.*]]
+; CHECK:       unwind_out:
+; CHECK-NEXT:    catchret from [[CATCHPAD]] to label [[LEAVE:%.*]]
+; CHECK:       leave:
+; CHECK-NEXT:    ret void
+; CHECK:       loop_body:
+; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLAH:%.*]] ]
+; CHECK-NEXT:    [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
+; CHECK-NEXT:    [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
+; CHECK-NEXT:    br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
+; CHECK:       iter:
+; CHECK-NEXT:    br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]
+;
 entry:
   br label %throw
 
 throw:                                            ; preds = %throw, %entry
   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
   invoke void @reserve()
-          to label %throw unwind label %pad
+  to label %throw unwind label %pad
 
 pad:
   %phi2 = phi i8* [ %tmp96, %throw ]
@@ -84,20 +141,45 @@ iter:                                             ; preds = %loop_body
   br i1 undef, label %unwind_out, label %loop_body
 }
 
-; CHECK-LABEL: define void @g(
-; CHECK: blah:
-; CHECK-NEXT: catchpad within %cs []
-; CHECK-NEXT: ptrtoint i8* %phi2 to i32
-
-
 define void @h() personality i32 (...)* @_except_handler3 {
+; CHECK-LABEL: @h(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[THROW:%.*]]
+; CHECK:       throw:
+; CHECK-NEXT:    [[TMP96:%.*]] = getelementptr inbounds i8, i8* undef, i32 1
+; CHECK-NEXT:    invoke void @reserve()
+; CHECK-NEXT:    to label [[THROW]] unwind label [[PAD:%.*]]
+; CHECK:       pad:
+; CHECK-NEXT:    [[CS:%.*]] = catchswitch within none [label [[UNREACHABLE:%.*]], label %blug] unwind to caller
+; CHECK:       unreachable:
+; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS]] []
+; CHECK-NEXT:    unreachable
+; CHECK:       blug:
+; CHECK-NEXT:    [[PHI2:%.*]] = phi i8* [ [[TMP96]], [[PAD]] ]
+; CHECK-NEXT:    [[CATCHPAD:%.*]] = catchpad within [[CS]] []
+; CHECK-NEXT:    [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 1, [[PHI21]]
+; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP1]]
+; CHECK-NEXT:    br label [[LOOP_BODY:%.*]]
+; CHECK:       unwind_out:
+; CHECK-NEXT:    catchret from [[CATCHPAD]] to label [[LEAVE:%.*]]
+; CHECK:       leave:
+; CHECK-NEXT:    ret void
+; CHECK:       loop_body:
+; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[BLUG:%.*]] ]
+; CHECK-NEXT:    [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
+; CHECK-NEXT:    [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
+; CHECK-NEXT:    br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
+; CHECK:       iter:
+; CHECK-NEXT:    br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]
+;
 entry:
   br label %throw
 
 throw:                                            ; preds = %throw, %entry
   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
   invoke void @reserve()
-          to label %throw unwind label %pad
+  to label %throw unwind label %pad
 
 pad:
   %cs = catchswitch within none [label %unreachable, label %blug] unwind to caller
@@ -127,19 +209,45 @@ iter:                                             ; preds = %loop_body
   br i1 undef, label %unwind_out, label %loop_body
 }
 
-; CHECK-LABEL: define void @h(
-; CHECK: blug:
-; CHECK: catchpad within %cs []
-; CHECK-NEXT: ptrtoint i8* %phi2 to i32
-
 define void @i() personality i32 (...)* @_except_handler3 {
+; CHECK-LABEL: @i(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[THROW:%.*]]
+; CHECK:       throw:
+; CHECK-NEXT:    [[TMP96:%.*]] = getelementptr inbounds i8, i8* undef, i32 1
+; CHECK-NEXT:    invoke void @reserve()
+; CHECK-NEXT:    to label [[THROW]] unwind label [[CATCHPAD:%.*]]
+; CHECK:       catchpad:
+; CHECK-NEXT:    [[PHI2:%.*]] = phi i8* [ [[TMP96]], [[THROW]] ]
+; CHECK-NEXT:    [[CS:%.*]] = catchswitch within none [label %cp_body] unwind label [[CLEANUPPAD:%.*]]
+; CHECK:       cp_body:
+; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS]] []
+; CHECK-NEXT:    br label [[LOOP_HEAD:%.*]]
+; CHECK:       cleanuppad:
+; CHECK-NEXT:    [[TMP1:%.*]] = cleanuppad within none []
+; CHECK-NEXT:    br label [[LOOP_HEAD]]
+; CHECK:       loop_head:
+; CHECK-NEXT:    [[PHI21:%.*]] = ptrtoint i8* [[PHI2]] to i32
+; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 1, [[PHI21]]
+; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, i8* undef, i32 [[TMP2]]
+; CHECK-NEXT:    br label [[LOOP_BODY:%.*]]
+; CHECK:       loop_body:
+; CHECK-NEXT:    [[LSR_IV:%.*]] = phi i8* [ [[SCEVGEP2:%.*]], [[ITER:%.*]] ], [ [[SCEVGEP]], [[LOOP_HEAD]] ]
+; CHECK-NEXT:    [[SCEVGEP2]] = getelementptr i8, i8* [[LSR_IV]], i32 -1
+; CHECK-NEXT:    [[TMP100:%.*]] = icmp eq i8* [[SCEVGEP2]], null
+; CHECK-NEXT:    br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]]
+; CHECK:       iter:
+; CHECK-NEXT:    br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]]
+; CHECK:       unwind_out:
+; CHECK-NEXT:    unreachable
+;
 entry:
   br label %throw
 
 throw:                                            ; preds = %throw, %entry
   %tmp96 = getelementptr inbounds i8, i8* undef, i32 1
   invoke void @reserve()
-          to label %throw unwind label %catchpad
+  to label %throw unwind label %catchpad
 
 catchpad:                                              ; preds = %throw
   %phi2 = phi i8* [ %tmp96, %throw ]
@@ -169,17 +277,41 @@ unwind_out:                                       ; preds = %iter, %loop_body
   unreachable
 }
 
-; CHECK-LABEL: define void @i(
-; CHECK: ptrtoint i8* %phi2 to i32
-
 define void @test1(i32* %b, i32* %c) personality i32 (...)* @__CxxFrameHandler3 {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_COND:%.*]]
+; CHECK:       for.cond:
+; CHECK-NEXT:    [[D_0:%.*]] = phi i32* [ [[B:%.*]], [[ENTRY:%.*]] ], [ [[INCDEC_PTR:%.*]], [[FOR_INC:%.*]] ]
+; CHECK-NEXT:    invoke void @external(i32* [[D_0]])
+; CHECK-NEXT:    to label [[FOR_INC]] unwind label [[CATCH_DISPATCH:%.*]]
+; CHECK:       for.inc:
+; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr inbounds i32, i32* [[D_0]], i32 1
+; CHECK-NEXT:    br label [[FOR_COND]]
+; CHECK:       catch.dispatch:
+; CHECK-NEXT:    [[CS:%.*]] = catchswitch within none [label %catch] unwind label [[CATCH_DISPATCH_2:%.*]]
+; CHECK:       catch:
+; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS]] [i8* null, i32 64, i8* null]
+; CHECK-NEXT:    catchret from [[TMP0]] to label [[TRY_CONT:%.*]]
+; CHECK:       try.cont:
+; CHECK-NEXT:    invoke void @external(i32* [[C:%.*]])
+; CHECK-NEXT:    to label [[TRY_CONT_7:%.*]] unwind label [[CATCH_DISPATCH_2]]
+; CHECK:       catch.dispatch.2:
+; CHECK-NEXT:    [[E_0:%.*]] = phi i32* [ [[C]], [[TRY_CONT]] ], [ [[B]], [[CATCH_DISPATCH]] ]
+; CHECK-NEXT:    [[CS2:%.*]] = catchswitch within none [label %catch.4] unwind to caller
+; CHECK:       catch.4:
+; CHECK-NEXT:    [[TMP1:%.*]] = catchpad within [[CS2]] [i8* null, i32 64, i8* null]
+; CHECK-NEXT:    unreachable
+; CHECK:       try.cont.7:
+; CHECK-NEXT:    ret void
+;
 entry:
   br label %for.cond
 
 for.cond:                                         ; preds = %for.inc, %entry
   %d.0 = phi i32* [ %b, %entry ], [ %incdec.ptr, %for.inc ]
   invoke void @external(i32* %d.0)
-          to label %for.inc unwind label %catch.dispatch
+  to label %for.inc unwind label %catch.dispatch
 
 for.inc:                                          ; preds = %for.cond
   %incdec.ptr = getelementptr inbounds i32, i32* %d.0, i32 1
@@ -194,7 +326,7 @@ catch:                                            ; preds = %catch.dispatch
 
 try.cont:                                         ; preds = %catch
   invoke void @external(i32* %c)
-          to label %try.cont.7 unwind label %catch.dispatch.2
+  to label %try.cont.7 unwind label %catch.dispatch.2
 
 catch.dispatch.2:                                 ; preds = %try.cont, %catchendblock
   %e.0 = phi i32* [ %c, %try.cont ], [ %b, %catch.dispatch ]
@@ -208,21 +340,33 @@ try.cont.7:                                       ; preds = %try.cont
   ret void
 }
 
-; CHECK-LABEL: define void @test1(
-; CHECK: for.cond:
-; CHECK:   %d.0 = phi i32* [ %b, %entry ], [ %incdec.ptr, %for.inc ]
-
-; CHECK: catch.dispatch.2:
-; CHECK: %e.0 = phi i32* [ %c, %try.cont ], [ %b, %catch.dispatch ]
-
 define i32 @test2() personality i32 (...)* @_except_handler3 {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
+; CHECK:       for.body:
+; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    invoke void @reserve()
+; CHECK-NEXT:    to label [[FOR_INC]] unwind label [[CATCH_DISPATCH:%.*]]
+; CHECK:       catch.dispatch:
+; CHECK-NEXT:    [[TMP18:%.*]] = catchswitch within none [label %catch.handler] unwind to caller
+; CHECK:       catch.handler:
+; CHECK-NEXT:    [[PHI_LCSSA:%.*]] = phi i32 [ [[PHI]], [[CATCH_DISPATCH]] ]
+; CHECK-NEXT:    [[TMP19:%.*]] = catchpad within [[TMP18]] [i8* null]
+; CHECK-NEXT:    catchret from [[TMP19]] to label [[DONE:%.*]]
+; CHECK:       done:
+; CHECK-NEXT:    ret i32 [[PHI_LCSSA]]
+; CHECK:       for.inc:
+; CHECK-NEXT:    [[INC]] = add i32 [[PHI]], 1
+; CHECK-NEXT:    br label [[FOR_BODY]]
+;
 entry:
   br label %for.body
 
 for.body:                                         ; preds = %for.inc, %entry
   %phi = phi i32 [ %inc, %for.inc ], [ 0, %entry ]
   invoke void @reserve()
-          to label %for.inc unwind label %catch.dispatch
+  to label %for.inc unwind label %catch.dispatch
 
 catch.dispatch:                                   ; preds = %for.body
   %tmp18 = catchswitch within none [label %catch.handler] unwind to caller
@@ -239,7 +383,3 @@ for.inc:                                          ; preds = %for.body
   %inc = add i32 %phi, 1
   br label %for.body
 }
-
-; CHECK-LABEL: define i32 @test2(
-; CHECK:      %phi.lcssa = phi i32 [ %phi, %catch.dispatch ]
-; CHECK-NEXT: catchpad within
diff --git a/llvm/test/Transforms/LoopStrengthReduce/scev-expander-lcssa.ll b/llvm/test/Transforms/LoopStrengthReduce/scev-expander-lcssa.ll
new file mode 100644 (file)
index 0000000..e05dcda
--- /dev/null
@@ -0,0 +1,144 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -loop-reduce -S %s | FileCheck %s
+
+; Make sure SCEVExpander does not crash and introduce unnecessary LCSSA PHI nodes.
+
+define void @schedule_block() {
+; CHECK-LABEL: @schedule_block(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    switch i16 undef, label [[IF_END156_I:%.*]] [
+; CHECK-NEXT:    i16 27, label [[IF_THEN_I:%.*]]
+; CHECK-NEXT:    i16 28, label [[IF_THEN_I]]
+; CHECK-NEXT:    i16 29, label [[IF_THEN13_I:%.*]]
+; CHECK-NEXT:    i16 32, label [[LAND_LHS_TRUE136_I:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       if.then.i:
+; CHECK-NEXT:    unreachable
+; CHECK:       if.then13.i:
+; CHECK-NEXT:    unreachable
+; CHECK:       land.lhs.true136.i:
+; CHECK-NEXT:    unreachable
+; CHECK:       if.end156.i:
+; CHECK-NEXT:    switch i16 undef, label [[WHILE_END256:%.*]] [
+; CHECK-NEXT:    i16 29, label [[IF_THEN210:%.*]]
+; CHECK-NEXT:    i16 28, label [[IF_THEN210]]
+; CHECK-NEXT:    i16 27, label [[LAND_LHS_TRUE191:%.*]]
+; CHECK-NEXT:    i16 32, label [[IF_END248:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       land.lhs.true191:
+; CHECK-NEXT:    unreachable
+; CHECK:       if.then210:
+; CHECK-NEXT:    unreachable
+; CHECK:       if.end248:
+; CHECK-NEXT:    br label [[FOR_END:%.*]]
+; CHECK:       while.end256:
+; CHECK-NEXT:    unreachable
+; CHECK:       for.end:
+; CHECK-NEXT:    br label [[WHILE_BODY1013:%.*]]
+; CHECK:       while.body1013:
+; CHECK-NEXT:    br label [[FOR_COND_I2472:%.*]]
+; CHECK:       for.cond.i2472:
+; CHECK-NEXT:    [[I_0_I:%.*]] = phi i32 [ 0, [[WHILE_BODY1013]] ], [ [[TMP2:%.*]], [[FOR_END34_I:%.*]] ]
+; CHECK-NEXT:    br i1 false, label [[FOR_COND3_PREHEADER_I:%.*]], label [[IF_END107_I_LOOPEXIT:%.*]]
+; CHECK:       for.cond3.preheader.i:
+; CHECK-NEXT:    [[TMP0:%.*]] = sext i32 [[I_0_I]] to i64
+; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], 1
+; CHECK-NEXT:    br label [[FOR_COND3_I:%.*]]
+; CHECK:       for.cond3.i:
+; CHECK-NEXT:    [[INDVARS_IV301_I2691:%.*]] = phi i64 [ [[INDVARS_IV_NEXT302_I:%.*]], [[FOR_BODY5_I:%.*]] ], [ [[TMP1]], [[FOR_COND3_PREHEADER_I]] ]
+; CHECK-NEXT:    [[INDVARS_IV_NEXT302_I]] = add nsw i64 [[INDVARS_IV301_I2691]], 1
+; CHECK-NEXT:    br label [[FOR_BODY5_I]]
+; CHECK:       for.body5.i:
+; CHECK-NEXT:    br i1 false, label [[FOR_COND3_I]], label [[FOR_BODY5_I_FOR_END_I2475_LOOPEXIT_CRIT_EDGE:%.*]]
+; CHECK:       for.body5.i.for.end.i2475.loopexit_crit_edge:
+; CHECK-NEXT:    [[TMP2]] = trunc i64 [[INDVARS_IV_NEXT302_I]] to i32
+; CHECK-NEXT:    br label [[FOR_END34_I]]
+; CHECK:       for.end34.i:
+; CHECK-NEXT:    br i1 false, label [[FOR_COND_I2472]], label [[IF_ELSE_I2488:%.*]]
+; CHECK:       if.else.i2488:
+; CHECK-NEXT:    br i1 undef, label [[IF_END107_I:%.*]], label [[FOR_BODY45_PREHEADER_I:%.*]]
+; CHECK:       for.body45.preheader.i:
+; CHECK-NEXT:    [[TMP3:%.*]] = sext i32 [[I_0_I]] to i64
+; CHECK-NEXT:    unreachable
+; CHECK:       if.end107.i.loopexit:
+; CHECK-NEXT:    br label [[IF_END107_I]]
+; CHECK:       if.end107.i:
+; CHECK-NEXT:    unreachable
+;
+entry:
+  switch i16 undef, label %if.end156.i [
+  i16 27, label %if.then.i
+  i16 28, label %if.then.i
+  i16 29, label %if.then13.i
+  i16 32, label %land.lhs.true136.i
+  ]
+
+if.then.i:                                        ; preds = %entry, %entry
+  unreachable
+
+if.then13.i:                                      ; preds = %entry
+  unreachable
+
+land.lhs.true136.i:                               ; preds = %entry
+  unreachable
+
+if.end156.i:                                      ; preds = %entry
+  switch i16 undef, label %while.end256 [
+  i16 29, label %if.then210
+  i16 28, label %if.then210
+  i16 27, label %land.lhs.true191
+  i16 32, label %if.end248
+  ]
+
+land.lhs.true191:                                 ; preds = %if.end156.i
+  unreachable
+
+if.then210:                                       ; preds = %if.end156.i, %if.end156.i
+  unreachable
+
+if.end248:                                        ; preds = %if.end156.i
+  br label %for.end
+
+while.end256:                                     ; preds = %if.end156.i
+  unreachable
+
+for.end:                                          ; preds = %if.end248
+  br label %while.body1013
+
+while.body1013:                                   ; preds = %for.end
+  br label %for.cond.i2472
+
+for.cond.i2472:                                   ; preds = %for.end34.i, %while.body1013
+  %i.0.i = phi i32 [ 0, %while.body1013 ], [ %2, %for.end34.i ]
+  br i1 undef, label %for.cond3.preheader.i, label %if.end107.i
+
+for.cond3.preheader.i:                            ; preds = %for.cond.i2472
+  %0 = sext i32 %i.0.i to i64
+  %1 = add nsw i64 %0, 1
+  br label %for.cond3.i
+
+for.cond3.i:                                      ; preds = %for.body5.i, %for.cond3.preheader.i
+  %indvars.iv301.i2691 = phi i64 [ %indvars.iv.next302.i, %for.body5.i ], [ %1, %for.cond3.preheader.i ]
+  %indvars.iv.next302.i = add nsw i64 %indvars.iv301.i2691, 1
+  br label %for.body5.i
+
+for.body5.i:                                      ; preds = %for.cond3.i
+  br i1 undef, label %for.cond3.i, label %for.body5.i.for.end.i2475.loopexit_crit_edge
+
+for.body5.i.for.end.i2475.loopexit_crit_edge:     ; preds = %for.body5.i
+  %2 = trunc i64 %indvars.iv.next302.i to i32
+  br label %for.end34.i
+
+for.end34.i:                                      ; preds = %for.body5.i.for.end.i2475.loopexit_crit_edge
+  br i1 undef, label %for.cond.i2472, label %if.else.i2488
+
+if.else.i2488:                                    ; preds = %for.end34.i
+  br i1 undef, label %if.end107.i, label %for.body45.preheader.i
+
+for.body45.preheader.i:                           ; preds = %if.else.i2488
+  %3 = sext i32 %i.0.i to i64
+  unreachable
+
+if.end107.i:                                      ; preds = %if.else.i2488, %for.cond.i2472
+  unreachable
+}