Skip to content

Commit 16c6c48

Browse files
authored
IndVarSimplify: add samesign test from a regression (#125539)
While attempting to teach ScalarEvolution about samesign in another effort, a complicated testcase with nested loops, and zero-extends of the induction-variable regresses, but only when the target datalayout is present. The regression was originally reported on IndVarSimplify, but an improvement of symbolic BTC was also observed on SCEV. Check in the test into both IndVarSimplify and SCEV, to ease investigation and further development.
1 parent a3321ea commit 16c6c48

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -disable-output "-passes=print<scalar-evolution>" \
3+
; RUN: -scalar-evolution-classify-expressions=0 < %s 2>&1 | FileCheck %s
4+
5+
define i32 @exit_count_samesign(i32 %iter.count, ptr %ptr) {
6+
; CHECK-LABEL: 'exit_count_samesign'
7+
; CHECK-NEXT: Determining loop execution counts for: @exit_count_samesign
8+
; CHECK-NEXT: Loop %inner.loop: backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
9+
; CHECK-NEXT: Loop %inner.loop: constant max backedge-taken count is i32 2147483646
10+
; CHECK-NEXT: Loop %inner.loop: symbolic max backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
11+
; CHECK-NEXT: Loop %inner.loop: Trip multiple is 1
12+
; CHECK-NEXT: Loop %outer.loop: <multiple exits> Unpredictable backedge-taken count.
13+
; CHECK-NEXT: Loop %outer.loop: Unpredictable constant max backedge-taken count.
14+
; CHECK-NEXT: Loop %outer.loop: Unpredictable symbolic max backedge-taken count.
15+
;
16+
entry:
17+
br label %outer.loop
18+
19+
ph:
20+
br label %outer.loop
21+
22+
outer.loop:
23+
%iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
24+
%iv.outer.1 = add nsw i32 %iv.outer, -1
25+
%ext.outer = zext nneg i32 %iv.outer.1 to i64
26+
%gep.outer = getelementptr double, ptr %ptr, i64 %ext.outer
27+
store double poison, ptr %gep.outer
28+
%exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1
29+
br i1 %exit.cond.outer, label %inner.loop, label %ph
30+
31+
inner.loop:
32+
%iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
33+
%ext.inner = zext nneg i32 %iv.inner to i64
34+
%gep.inner = getelementptr double, ptr %ptr, i64 %ext.inner
35+
store double poison, ptr %gep.inner
36+
%iv.next = add nuw nsw i32 %iv.inner, 1
37+
%exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
38+
br i1 %exit.cond.inner, label %inner.loop, label %ph
39+
40+
exit:
41+
ret i32 0
42+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=indvars -S | FileCheck %s
3+
4+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
5+
6+
define i32 @iv_zext_samesign(i32 %iter.count, ptr %ptr) {
7+
; CHECK-LABEL: define i32 @iv_zext_samesign(
8+
; CHECK-SAME: i32 [[ITER_COUNT:%.*]], ptr [[PTR:%.*]]) {
9+
; CHECK-NEXT: [[ENTRY:.*]]:
10+
; CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[ITER_COUNT]] to i64
11+
; CHECK-NEXT: br label %[[OUTER_LOOP:.*]]
12+
; CHECK: [[PH_LOOPEXIT:.*]]:
13+
; CHECK-NEXT: br label %[[PH:.*]]
14+
; CHECK: [[PH]]:
15+
; CHECK-NEXT: br label %[[OUTER_LOOP]]
16+
; CHECK: [[OUTER_LOOP]]:
17+
; CHECK-NEXT: [[INDVARS_IV1:%.*]] = phi i64 [ [[INDVARS_IV_NEXT2:%.*]], %[[PH]] ], [ [[TMP0]], %[[ENTRY]] ]
18+
; CHECK-NEXT: [[INDVARS_IV_NEXT2]] = add nsw i64 [[INDVARS_IV1]], -1
19+
; CHECK-NEXT: [[GEP_OUTER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV_NEXT2]]
20+
; CHECK-NEXT: store double poison, ptr [[GEP_OUTER]], align 8
21+
; CHECK-NEXT: [[TMP1:%.*]] = trunc nsw i64 [[INDVARS_IV1]] to i32
22+
; CHECK-NEXT: [[EXIT_COND_OUTER:%.*]] = icmp samesign ugt i32 [[TMP1]], 1
23+
; CHECK-NEXT: br i1 [[EXIT_COND_OUTER]], label %[[INNER_LOOP_PREHEADER:.*]], label %[[PH]]
24+
; CHECK: [[INNER_LOOP_PREHEADER]]:
25+
; CHECK-NEXT: br label %[[INNER_LOOP:.*]]
26+
; CHECK: [[INNER_LOOP]]:
27+
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[INNER_LOOP_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[INNER_LOOP]] ]
28+
; CHECK-NEXT: [[GEP_INNER:%.*]] = getelementptr double, ptr [[PTR]], i64 [[INDVARS_IV]]
29+
; CHECK-NEXT: store double poison, ptr [[GEP_INNER]], align 8
30+
; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1
31+
; CHECK-NEXT: [[EXIT_COND_INNER:%.*]] = icmp slt i64 [[INDVARS_IV_NEXT]], [[INDVARS_IV_NEXT2]]
32+
; CHECK-NEXT: br i1 [[EXIT_COND_INNER]], label %[[INNER_LOOP]], label %[[PH_LOOPEXIT]]
33+
; CHECK: [[EXIT:.*:]]
34+
; CHECK-NEXT: ret i32 0
35+
;
36+
entry:
37+
br label %outer.loop
38+
39+
ph:
40+
br label %outer.loop
41+
42+
outer.loop:
43+
%iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
44+
%iv.outer.1 = add nsw i32 %iv.outer, -1
45+
%ext.outer = zext nneg i32 %iv.outer.1 to i64
46+
%gep.outer = getelementptr double, ptr %ptr, i64 %ext.outer
47+
store double poison, ptr %gep.outer
48+
%exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1
49+
br i1 %exit.cond.outer, label %inner.loop, label %ph
50+
51+
inner.loop:
52+
%iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
53+
%ext.inner = zext nneg i32 %iv.inner to i64
54+
%gep.inner = getelementptr double, ptr %ptr, i64 %ext.inner
55+
store double poison, ptr %gep.inner
56+
%iv.next = add nuw nsw i32 %iv.inner, 1
57+
%exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
58+
br i1 %exit.cond.inner, label %inner.loop, label %ph
59+
60+
exit:
61+
ret i32 0
62+
}

0 commit comments

Comments
 (0)