xref: /llvm-project/llvm/test/Transforms/InstCombine/add-sext-icmp.ll (revision 4f7dc1b55ae5b8ed1a36dd941ef4f9920bfdac8d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2; RUN: opt -S -passes=instcombine < %s | FileCheck %s
3
4; The pattern:
5;   add(add A, 1), (sext(icmp ne A, 0))
6; is transformed into:
7;   umax(A, 1)
8
9define i32 @add_sext_icmp(i32 %A) {
10; CHECK-LABEL: define i32 @add_sext_icmp(
11; CHECK-SAME: i32 [[A:%.*]]) {
12; CHECK-NEXT:    [[ADD2:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 1)
13; CHECK-NEXT:    ret i32 [[ADD2]]
14;
15  %add1 = add i32 %A, 1
16  %icmp = icmp ne i32 %A, 0
17  %sext = sext i1 %icmp to i32
18  %add2 = add i32 %add1, %sext
19  ret i32 %add2
20}
21
22define i32 @add_sext_icmp_commutative(i32 %A) {
23; CHECK-LABEL: define i32 @add_sext_icmp_commutative(
24; CHECK-SAME: i32 [[A:%.*]]) {
25; CHECK-NEXT:    [[ADD2:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 1)
26; CHECK-NEXT:    ret i32 [[ADD2]]
27;
28  %add1 = add i32 %A, 1
29  %icmp = icmp ne i32 %A, 0
30  %sext = sext i1 %icmp to i32
31  %add2 = add i32 %sext, %add1
32  ret i32 %add2
33}
34
35; Negative test
36
37define i32 @add_sext_icmp_negative_constant(i32 %A) {
38; CHECK-LABEL: define i32 @add_sext_icmp_negative_constant(
39; CHECK-SAME: i32 [[A:%.*]]) {
40; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A]], 2
41; CHECK-NEXT:    [[ICMP:%.*]] = icmp ne i32 [[A]], 0
42; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i32
43; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], [[SEXT]]
44; CHECK-NEXT:    ret i32 [[ADD2]]
45;
46  %add1 = add i32 %A, 2
47  %icmp = icmp ne i32 %A, 0
48  %sext = sext i1 %icmp to i32
49  %add2 = add i32 %add1, %sext
50  ret i32 %add2
51}
52
53define i32 @add_sext_icmp_negative_pred(i32 %A) {
54; CHECK-LABEL: define i32 @add_sext_icmp_negative_pred(
55; CHECK-SAME: i32 [[A:%.*]]) {
56; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A]], 1
57; CHECK-NEXT:    [[ICMP:%.*]] = icmp eq i32 [[A]], 0
58; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i32
59; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], [[SEXT]]
60; CHECK-NEXT:    ret i32 [[ADD2]]
61;
62  %add1 = add i32 %A, 1
63  %icmp = icmp eq i32 %A, 0
64  %sext = sext i1 %icmp to i32
65  %add2 = add i32 %add1, %sext
66  ret i32 %add2
67}
68
69; multi-use test
70
71define i32 @add_sext_icmp_multi_use_add2(i32 %A) {
72; CHECK-LABEL: define i32 @add_sext_icmp_multi_use_add2(
73; CHECK-SAME: i32 [[A:%.*]]) {
74; CHECK-NEXT:    [[ADD2:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 1)
75; CHECK-NEXT:    call void @use(i32 [[ADD2]])
76; CHECK-NEXT:    ret i32 [[ADD2]]
77;
78  %add1 = add i32 %A, 1
79  %icmp = icmp ne i32 %A, 0
80  %sext = sext i1 %icmp to i32
81  %add2 = add i32 %add1, %sext
82  call void @use(i32 %add2)
83  ret i32 %add2
84}
85
86define i32 @add_sext_icmp_multi_use_sext(i32 %A) {
87; CHECK-LABEL: define i32 @add_sext_icmp_multi_use_sext(
88; CHECK-SAME: i32 [[A:%.*]]) {
89; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A]], 1
90; CHECK-NEXT:    [[ICMP:%.*]] = icmp ne i32 [[A]], 0
91; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i32
92; CHECK-NEXT:    call void @use(i32 [[SEXT]])
93; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], [[SEXT]]
94; CHECK-NEXT:    ret i32 [[ADD2]]
95;
96  %add1 = add i32 %A, 1
97  %icmp = icmp ne i32 %A, 0
98  %sext = sext i1 %icmp to i32
99  call void @use(i32 %sext)
100  %add2 = add i32 %add1, %sext
101  ret i32 %add2
102}
103
104define i32 @add_sext_icmp_multi_use_icmp(i32 %A) {
105; CHECK-LABEL: define i32 @add_sext_icmp_multi_use_icmp(
106; CHECK-SAME: i32 [[A:%.*]]) {
107; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A]], 1
108; CHECK-NEXT:    [[ICMP:%.*]] = icmp ne i32 [[A]], 0
109; CHECK-NEXT:    call void @use(i1 [[ICMP]])
110; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[ICMP]] to i32
111; CHECK-NEXT:    [[ADD2:%.*]] = add i32 [[ADD1]], [[SEXT]]
112; CHECK-NEXT:    ret i32 [[ADD2]]
113;
114  %add1 = add i32 %A, 1
115  %icmp = icmp ne i32 %A, 0
116  call void @use(i1 %icmp)
117  %sext = sext i1 %icmp to i32
118  %add2 = add i32 %add1, %sext
119  ret i32 %add2
120}
121
122define i32 @add_sext_icmp_multi_use_add1(i32 %A) {
123; CHECK-LABEL: define i32 @add_sext_icmp_multi_use_add1(
124; CHECK-SAME: i32 [[A:%.*]]) {
125; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[A]], 1
126; CHECK-NEXT:    call void @use(i32 [[ADD1]])
127; CHECK-NEXT:    [[ADD2:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 1)
128; CHECK-NEXT:    ret i32 [[ADD2]]
129;
130  %add1 = add i32 %A, 1
131  call void @use(i32 %add1)
132  %icmp = icmp ne i32 %A, 0
133  %sext = sext i1 %icmp to i32
134  %add2 = add i32 %add1, %sext
135  ret i32 %add2
136}
137
138declare void @use(i32)
139
140