xref: /llvm-project/llvm/test/Transforms/IndVarSimplify/X86/widening-vs-and-elimination.ll (revision f3e2f26378400dbc785691ec38158ef4019208f8)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -passes=indvars < %s | FileCheck %s --check-prefixes=WIDENING_ON
3; RUN: opt -S -passes=indvars -indvars-widen-indvars=false < %s | FileCheck %s --check-prefixes=WIDENING_OFF
4
5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
6target triple = "x86_64-unknown-linux-gnu"
7
8define void @test_01(i32 %start, i32 %limit) {
9; WIDENING_ON-LABEL: @test_01(
10; WIDENING_ON-NEXT:  bb:
11; WIDENING_ON-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
12; WIDENING_ON-NEXT:    [[TMP1:%.*]] = add nsw i64 [[TMP0]], -1
13; WIDENING_ON-NEXT:    [[TMP2:%.*]] = zext i32 [[LIMIT:%.*]] to i64
14; WIDENING_ON-NEXT:    [[RANGE_CHECK_WIDE_FIRST_ITER:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]]
15; WIDENING_ON-NEXT:    br label [[LOOP:%.*]]
16; WIDENING_ON:       loop:
17; WIDENING_ON-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[BB:%.*]] ]
18; WIDENING_ON-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
19; WIDENING_ON-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i64 [[INDVARS_IV]], 0
20; WIDENING_ON-NEXT:    [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK_WIDE_FIRST_ITER]]
21; WIDENING_ON-NEXT:    br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]]
22; WIDENING_ON:       backedge:
23; WIDENING_ON-NEXT:    br label [[LOOP]]
24; WIDENING_ON:       exit:
25; WIDENING_ON-NEXT:    ret void
26;
27; WIDENING_OFF-LABEL: @test_01(
28; WIDENING_OFF-NEXT:  bb:
29; WIDENING_OFF-NEXT:    [[TMP0:%.*]] = add i32 [[START:%.*]], -1
30; WIDENING_OFF-NEXT:    [[RANGE_CHECK_FIRST_ITER:%.*]] = icmp ult i32 [[TMP0]], [[LIMIT:%.*]]
31; WIDENING_OFF-NEXT:    br label [[LOOP:%.*]]
32; WIDENING_OFF:       loop:
33; WIDENING_OFF-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[START]], [[BB:%.*]] ]
34; WIDENING_OFF-NEXT:    [[IV_NEXT]] = add i32 [[IV]], -1
35; WIDENING_OFF-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i32 [[IV]], 0
36; WIDENING_OFF-NEXT:    [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK_FIRST_ITER]]
37; WIDENING_OFF-NEXT:    br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]]
38; WIDENING_OFF:       backedge:
39; WIDENING_OFF-NEXT:    [[ZEXT:%.*]] = zext i32 [[IV_NEXT]] to i64
40; WIDENING_OFF-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, ptr addrspace(1) poison, i64 [[ZEXT]]
41; WIDENING_OFF-NEXT:    br label [[LOOP]]
42; WIDENING_OFF:       exit:
43; WIDENING_OFF-NEXT:    ret void
44;
45bb:
46  br label %loop
47
48loop:                                              ; preds = %backedge, %bb
49  %iv = phi i32 [ %iv.next, %backedge ], [ %start, %bb ]
50  %iv.next = add i32 %iv, -1
51  %not.zero = icmp ne i32 %iv, 0
52  %range.check = icmp ult i32 %iv.next, %limit
53  %and = and i1 %not.zero, %range.check
54  br i1 %and, label %backedge, label %exit
55
56backedge:                                              ; preds = %loop
57  %zext = zext i32 %iv.next to i64
58  %gep = getelementptr inbounds i32, ptr addrspace(1) poison, i64 %zext
59  br label %loop
60
61exit:                                             ; preds = %loop
62  ret void
63}
64
65define i32 @test_02(i32 %start, i32 %limit) {
66; WIDENING_ON-LABEL: @test_02(
67; WIDENING_ON-NEXT:  bb:
68; WIDENING_ON-NEXT:    [[TMP0:%.*]] = zext i32 [[START:%.*]] to i64
69; WIDENING_ON-NEXT:    br label [[LOOP:%.*]]
70; WIDENING_ON:       loop:
71; WIDENING_ON-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ [[TMP0]], [[BB:%.*]] ]
72; WIDENING_ON-NEXT:    [[CANONICAL_IV:%.*]] = phi i32 [ [[CANONICAL_IV_NEXT:%.*]], [[BACKEDGE]] ], [ 0, [[BB]] ]
73; WIDENING_ON-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[CANONICAL_IV]], 65635
74; WIDENING_ON-NEXT:    br i1 [[EXITCOND]], label [[CHECKED:%.*]], label [[FAILED:%.*]]
75; WIDENING_ON:       checked:
76; WIDENING_ON-NEXT:    [[TMP1:%.*]] = add nsw i64 [[INDVARS_IV]], -1
77; WIDENING_ON-NEXT:    [[INDVARS_IV_NEXT]] = add nsw i64 [[INDVARS_IV]], -1
78; WIDENING_ON-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i64 [[INDVARS_IV]], 0
79; WIDENING_ON-NEXT:    [[TMP2:%.*]] = zext i32 [[LIMIT:%.*]] to i64
80; WIDENING_ON-NEXT:    [[RANGE_CHECK_WIDE:%.*]] = icmp ult i64 [[TMP1]], [[TMP2]]
81; WIDENING_ON-NEXT:    [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK_WIDE]]
82; WIDENING_ON-NEXT:    br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]]
83; WIDENING_ON:       backedge:
84; WIDENING_ON-NEXT:    [[CANONICAL_IV_NEXT]] = add nuw nsw i32 [[CANONICAL_IV]], 1
85; WIDENING_ON-NEXT:    br label [[LOOP]]
86; WIDENING_ON:       exit:
87; WIDENING_ON-NEXT:    ret i32 0
88; WIDENING_ON:       failed:
89; WIDENING_ON-NEXT:    ret i32 1
90;
91; WIDENING_OFF-LABEL: @test_02(
92; WIDENING_OFF-NEXT:  bb:
93; WIDENING_OFF-NEXT:    br label [[LOOP:%.*]]
94; WIDENING_OFF:       loop:
95; WIDENING_OFF-NEXT:    [[CANONICAL_IV:%.*]] = phi i32 [ [[CANONICAL_IV_NEXT:%.*]], [[BACKEDGE:%.*]] ], [ 0, [[BB:%.*]] ]
96; WIDENING_OFF-NEXT:    [[IV:%.*]] = phi i32 [ [[IV_NEXT:%.*]], [[BACKEDGE]] ], [ [[START:%.*]], [[BB]] ]
97; WIDENING_OFF-NEXT:    [[EXITCOND:%.*]] = icmp ne i32 [[CANONICAL_IV]], 65635
98; WIDENING_OFF-NEXT:    br i1 [[EXITCOND]], label [[CHECKED:%.*]], label [[FAILED:%.*]]
99; WIDENING_OFF:       checked:
100; WIDENING_OFF-NEXT:    [[IV_NEXT]] = add i32 [[IV]], -1
101; WIDENING_OFF-NEXT:    [[NOT_ZERO:%.*]] = icmp ne i32 [[IV]], 0
102; WIDENING_OFF-NEXT:    [[RANGE_CHECK:%.*]] = icmp ult i32 [[IV_NEXT]], [[LIMIT:%.*]]
103; WIDENING_OFF-NEXT:    [[AND:%.*]] = and i1 [[NOT_ZERO]], [[RANGE_CHECK]]
104; WIDENING_OFF-NEXT:    br i1 [[AND]], label [[BACKEDGE]], label [[EXIT:%.*]]
105; WIDENING_OFF:       backedge:
106; WIDENING_OFF-NEXT:    [[ZEXT:%.*]] = zext i32 [[IV_NEXT]] to i64
107; WIDENING_OFF-NEXT:    [[GEP:%.*]] = getelementptr inbounds i32, ptr addrspace(1) poison, i64 [[ZEXT]]
108; WIDENING_OFF-NEXT:    [[CANONICAL_IV_NEXT]] = add nuw nsw i32 [[CANONICAL_IV]], 1
109; WIDENING_OFF-NEXT:    br label [[LOOP]]
110; WIDENING_OFF:       exit:
111; WIDENING_OFF-NEXT:    ret i32 0
112; WIDENING_OFF:       failed:
113; WIDENING_OFF-NEXT:    ret i32 1
114;
115bb:
116  br label %loop
117
118loop:                                              ; preds = %backedge, %bb
119  %canonical_iv = phi i32 [ %canonical_iv.next, %backedge ], [ 0, %bb ]
120  %iv = phi i32 [ %iv.next, %backedge ], [ %start, %bb ]
121  %canonical_iv_check = icmp ult i32 %canonical_iv, 65635
122  br i1 %canonical_iv_check, label %checked, label %failed
123
124checked:
125  %iv.next = add i32 %iv, -1
126  %not.zero = icmp ne i32 %iv, 0
127  %range.check = icmp ult i32 %iv.next, %limit
128  %and = and i1 %not.zero, %range.check
129  br i1 %and, label %backedge, label %exit
130
131backedge:                                              ; preds = %loop
132  %zext = zext i32 %iv.next to i64
133  %gep = getelementptr inbounds i32, ptr addrspace(1) poison, i64 %zext
134  %canonical_iv.next = add i32 %canonical_iv, 1
135  br label %loop
136
137exit:                                             ; preds = %loop
138  ret i32 0
139
140failed:
141  ret i32 1
142}
143