Skip to content

Commit e390991

Browse files
committed
SCEV, IndVarSimplify: add samesign test from a regression
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 95c0c78 commit e390991

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
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"
6+
7+
define i32 @exit_count_samesign(i32 %iter.count, ptr %ptr) {
8+
; CHECK-LABEL: 'exit_count_samesign'
9+
; CHECK-NEXT: Determining loop execution counts for: @exit_count_samesign
10+
; CHECK-NEXT: Loop %inner.loop: backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
11+
; CHECK-NEXT: Loop %inner.loop: constant max backedge-taken count is i32 2147483646
12+
; CHECK-NEXT: Loop %inner.loop: symbolic max backedge-taken count is (-1 + (1 smax {(-1 + %iter.count)<nsw>,+,-1}<nsw><%outer.loop>))<nsw>
13+
; CHECK-NEXT: Loop %inner.loop: Trip multiple is 1
14+
; CHECK-NEXT: Loop %outer.loop: <multiple exits> Unpredictable backedge-taken count.
15+
; CHECK-NEXT: Loop %outer.loop: Unpredictable constant max backedge-taken count.
16+
; CHECK-NEXT: Loop %outer.loop: Unpredictable symbolic max backedge-taken count.
17+
;
18+
entry:
19+
br label %outer.loop
20+
21+
ph:
22+
br label %outer.loop
23+
24+
outer.loop:
25+
%iv.outer = phi i32 [ %iv.outer.1, %ph ], [ %iter.count, %entry ]
26+
%iv.outer.1 = add nsw i32 %iv.outer, -1
27+
%ext.outer = zext nneg i32 %iv.outer.1 to i64
28+
%gep.outer = getelementptr double, ptr %ptr, i64 %ext.outer
29+
store double poison, ptr %gep.outer
30+
%exit.cond.outer = icmp samesign ugt i32 %iv.outer, 1
31+
br i1 %exit.cond.outer, label %inner.loop, label %ph
32+
33+
inner.loop:
34+
%iv.inner = phi i32 [ %iv.next, %inner.loop ], [ 0, %outer.loop ]
35+
%ext.inner = zext nneg i32 %iv.inner to i64
36+
%gep.inner = getelementptr double, ptr %ptr, i64 %ext.inner
37+
store double poison, ptr %gep.inner
38+
%iv.next = add nuw nsw i32 %iv.inner, 1
39+
%exit.cond.inner = icmp slt i32 %iv.next, %iv.outer.1
40+
br i1 %exit.cond.inner, label %inner.loop, label %ph
41+
42+
exit:
43+
ret i32 0
44+
}
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)