xref: /llvm-project/llvm/test/Transforms/InstCombine/reassociate-nuw.ll (revision a105877646d68e48cdeeeadd9d1e075dc3c5d68d)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=instcombine -S %s | FileCheck %s
3
4define i32 @reassoc_add_nuw(i32 %x) {
5; CHECK-LABEL: @reassoc_add_nuw(
6; CHECK-NEXT:    [[ADD1:%.*]] = add nuw i32 [[X:%.*]], 68
7; CHECK-NEXT:    ret i32 [[ADD1]]
8;
9  %add0 = add nuw i32 %x, 4
10  %add1 = add nuw i32 %add0, 64
11  ret i32 %add1
12}
13
14; This does the wrong thing because the sub is turned into an add of a
15; negative constant first which drops the nuw.
16define i32 @reassoc_sub_nuw(i32 %x) {
17; CHECK-LABEL: @reassoc_sub_nuw(
18; CHECK-NEXT:    [[SUB1:%.*]] = add i32 [[X:%.*]], -68
19; CHECK-NEXT:    ret i32 [[SUB1]]
20;
21  %sub0 = sub nuw i32 %x, 4
22  %sub1 = sub nuw i32 %sub0, 64
23  ret i32 %sub1
24}
25
26define i32 @reassoc_mul_nuw(i32 %x) {
27; CHECK-LABEL: @reassoc_mul_nuw(
28; CHECK-NEXT:    [[MUL1:%.*]] = mul nuw i32 [[X:%.*]], 260
29; CHECK-NEXT:    ret i32 [[MUL1]]
30;
31  %mul0 = mul nuw i32 %x, 4
32  %mul1 = mul nuw i32 %mul0, 65
33  ret i32 %mul1
34}
35
36define i32 @no_reassoc_add_nuw_none(i32 %x) {
37; CHECK-LABEL: @no_reassoc_add_nuw_none(
38; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[X:%.*]], 68
39; CHECK-NEXT:    ret i32 [[ADD1]]
40;
41  %add0 = add i32 %x, 4
42  %add1 = add nuw i32 %add0, 64
43  ret i32 %add1
44}
45
46define i32 @no_reassoc_add_none_nuw(i32 %x) {
47; CHECK-LABEL: @no_reassoc_add_none_nuw(
48; CHECK-NEXT:    [[ADD1:%.*]] = add i32 [[X:%.*]], 68
49; CHECK-NEXT:    ret i32 [[ADD1]]
50;
51  %add0 = add nuw i32 %x, 4
52  %add1 = add i32 %add0, 64
53  ret i32 %add1
54}
55
56define i32 @reassoc_x2_add_nuw(i32 %x, i32 %y) {
57; CHECK-LABEL: @reassoc_x2_add_nuw(
58; CHECK-NEXT:    [[ADD1:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]]
59; CHECK-NEXT:    [[ADD2:%.*]] = add nuw i32 [[ADD1]], 12
60; CHECK-NEXT:    ret i32 [[ADD2]]
61;
62  %add0 = add nuw i32 %x, 4
63  %add1 = add nuw i32 %y, 8
64  %add2 = add nuw i32 %add0, %add1
65  ret i32 %add2
66}
67
68define i32 @reassoc_x2_mul_nuw(i32 %x, i32 %y) {
69; CHECK-LABEL: @reassoc_x2_mul_nuw(
70; CHECK-NEXT:    [[MUL1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]]
71; CHECK-NEXT:    [[MUL2:%.*]] = mul nuw i32 [[MUL1]], 45
72; CHECK-NEXT:    ret i32 [[MUL2]]
73;
74  %mul0 = mul nuw i32 %x, 5
75  %mul1 = mul nuw i32 %y, 9
76  %mul2 = mul nuw i32 %mul0, %mul1
77  ret i32 %mul2
78}
79
80define i32 @reassoc_x2_sub_nuw(i32 %x, i32 %y) {
81; CHECK-LABEL: @reassoc_x2_sub_nuw(
82; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]
83; CHECK-NEXT:    [[SUB2:%.*]] = add i32 [[TMP1]], 4
84; CHECK-NEXT:    ret i32 [[SUB2]]
85;
86  %sub0 = sub nuw i32 %x, 4
87  %sub1 = sub nuw i32 %y, 8
88  %sub2 = sub nuw i32 %sub0, %sub1
89  ret i32 %sub2
90}
91
92define i32 @tryFactorization_add_nuw_mul_nuw(i32 %x) {
93; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw(
94; CHECK-NEXT:    [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 2
95; CHECK-NEXT:    ret i32 [[ADD2]]
96;
97  %mul1 = mul nuw i32 %x, 3
98  %add2 = add nuw i32 %mul1, %x
99  ret i32 %add2
100}
101
102define i32 @tryFactorization_add_nuw_mul_nuw_int_max(i32 %x) {
103; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_int_max(
104; CHECK-NEXT:    [[ADD2:%.*]] = shl nuw i32 [[X:%.*]], 31
105; CHECK-NEXT:    ret i32 [[ADD2]]
106;
107  %mul1 = mul nuw i32 %x, 2147483647
108  %add2 = add nuw i32 %mul1, %x
109  ret i32 %add2
110}
111
112define i32 @tryFactorization_add_mul_nuw(i32 %x) {
113; CHECK-LABEL: @tryFactorization_add_mul_nuw(
114; CHECK-NEXT:    [[ADD2:%.*]] = shl i32 [[X:%.*]], 2
115; CHECK-NEXT:    ret i32 [[ADD2]]
116;
117  %mul1 = mul i32 %x, 3
118  %add2 = add nuw i32 %mul1, %x
119  ret i32 %add2
120}
121
122define i32 @tryFactorization_add_nuw_mul(i32 %x) {
123; CHECK-LABEL: @tryFactorization_add_nuw_mul(
124; CHECK-NEXT:    [[ADD2:%.*]] = shl i32 [[X:%.*]], 2
125; CHECK-NEXT:    ret i32 [[ADD2]]
126;
127  %mul1 = mul nuw i32 %x, 3
128  %add2 = add i32 %mul1, %x
129  ret i32 %add2
130}
131
132define i32 @tryFactorization_add_nuw_mul_nuw_mul_nuw_var(i32 %x, i32 %y, i32 %z) {
133; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_nuw_var(
134; CHECK-NEXT:    [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
135; CHECK-NEXT:    [[ADD1:%.*]] = mul nuw i32 [[X:%.*]], [[MUL21]]
136; CHECK-NEXT:    ret i32 [[ADD1]]
137;
138  %mul1 = mul nuw i32 %x, %y
139  %mul2 = mul nuw i32 %x, %z
140  %add1 = add nuw i32 %mul1, %mul2
141  ret i32 %add1
142}
143
144define i32 @tryFactorization_add_nuw_mul_mul_nuw_var(i32 %x, i32 %y, i32 %z) {
145; CHECK-LABEL: @tryFactorization_add_nuw_mul_mul_nuw_var(
146; CHECK-NEXT:    [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
147; CHECK-NEXT:    [[ADD1:%.*]] = mul i32 [[X:%.*]], [[MUL21]]
148; CHECK-NEXT:    ret i32 [[ADD1]]
149;
150  %mul1 = mul i32 %x, %y
151  %mul2 = mul nuw i32 %x, %z
152  %add1 = add nuw i32 %mul1, %mul2
153  ret i32 %add1
154}
155
156define i32 @tryFactorization_add_nuw_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) {
157; CHECK-LABEL: @tryFactorization_add_nuw_mul_nuw_mul_var(
158; CHECK-NEXT:    [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
159; CHECK-NEXT:    [[ADD1:%.*]] = mul i32 [[X:%.*]], [[MUL21]]
160; CHECK-NEXT:    ret i32 [[ADD1]]
161;
162  %mul1 = mul nuw i32 %x, %y
163  %mul2 = mul i32 %x, %z
164  %add1 = add nuw i32 %mul1, %mul2
165  ret i32 %add1
166}
167
168define i32 @tryFactorization_add_mul_nuw_mul_var(i32 %x, i32 %y, i32 %z) {
169; CHECK-LABEL: @tryFactorization_add_mul_nuw_mul_var(
170; CHECK-NEXT:    [[MUL21:%.*]] = add i32 [[Y:%.*]], [[Z:%.*]]
171; CHECK-NEXT:    [[ADD1:%.*]] = mul i32 [[X:%.*]], [[MUL21]]
172; CHECK-NEXT:    ret i32 [[ADD1]]
173;
174  %mul1 = mul nuw i32 %x, %y
175  %mul2 = mul nuw i32 %x, %z
176  %add1 = add i32 %mul1, %mul2
177  ret i32 %add1
178}
179