xref: /llvm-project/llvm/test/Transforms/Reassociate/reassoc-mul-nuw.ll (revision 6e379de3b144363c2f5a6f9335eef6f42e28ef37)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
2; RUN: opt < %s -passes=reassociate -S | FileCheck %s
3
4; We cannot preserve nuw flags for mul
5define i4 @nuw_preserve_negative(i4 %a, i4 %b, i4 %c) {
6; CHECK-LABEL: define i4 @nuw_preserve_negative(
7; CHECK-SAME: i4 [[A:%.*]], i4 [[B:%.*]], i4 [[C:%.*]]) {
8; CHECK-NEXT:    [[V0:%.*]] = mul i4 [[B]], [[A]]
9; CHECK-NEXT:    [[V1:%.*]] = mul i4 [[V0]], [[C]]
10; CHECK-NEXT:    ret i4 [[V1]]
11;
12  %v0 = mul nuw i4 %a, %c
13  %v1 = mul nuw i4 %v0, %b
14  ret i4 %v1
15}
16
17; TODO: we can add nuw flags if we know all operands are non-zero.
18define i4 @nuw_preserve_non_zero(i4 %a, i4 %b, i4 %c) {
19; CHECK-LABEL: define i4 @nuw_preserve_non_zero(
20; CHECK-SAME: i4 [[A:%.*]], i4 [[B:%.*]], i4 [[C:%.*]]) {
21; CHECK-NEXT:    [[A0:%.*]] = add nuw i4 [[A]], 1
22; CHECK-NEXT:    [[B0:%.*]] = add nuw i4 [[B]], 1
23; CHECK-NEXT:    [[C0:%.*]] = add nuw i4 [[C]], 1
24; CHECK-NEXT:    [[V0:%.*]] = mul nuw i4 [[B0]], [[A0]]
25; CHECK-NEXT:    [[V1:%.*]] = mul nuw i4 [[V0]], [[C0]]
26; CHECK-NEXT:    ret i4 [[V1]]
27;
28  %a0 = add nuw i4 %a, 1
29  %b0 = add nuw i4 %b, 1
30  %c0 = add nuw i4 %c, 1
31  %v0 = mul nuw i4 %a0, %c0
32  %v1 = mul nuw i4 %v0, %b0
33  ret i4 %v1
34}
35
36define i4 @re_order_mul_nuw(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) {
37; CHECK-LABEL: define i4 @re_order_mul_nuw(
38; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) {
39; CHECK-NEXT:    [[X0:%.*]] = add nuw i4 [[XX0]], 1
40; CHECK-NEXT:    [[X1:%.*]] = add nuw i4 [[XX1]], 1
41; CHECK-NEXT:    [[X2:%.*]] = add nuw i4 [[XX2]], 1
42; CHECK-NEXT:    [[X3:%.*]] = add nuw i4 [[XX3]], 1
43; CHECK-NEXT:    [[MUL_B:%.*]] = mul nuw i4 [[X1]], [[X0]]
44; CHECK-NEXT:    [[MUL_A:%.*]] = mul nuw i4 [[MUL_B]], [[X2]]
45; CHECK-NEXT:    [[MUL_C:%.*]] = mul nuw i4 [[MUL_A]], [[X3]]
46; CHECK-NEXT:    ret i4 [[MUL_C]]
47;
48  %x0 = add nuw i4 %xx0, 1
49  %x1 = add nuw i4 %xx1, 1
50  %x2 = add nuw i4 %xx2, 1
51  %x3 = add nuw i4 %xx3, 1
52  %mul_a = mul nuw i4 %x0, %x1
53  %mul_b = mul nuw i4 %x2, %x3
54  %mul_c = mul nuw i4 %mul_a, %mul_b
55  ret i4 %mul_c
56}
57
58define i4 @re_order_mul_nuw_fail_maybe_zero(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) {
59; CHECK-LABEL: define i4 @re_order_mul_nuw_fail_maybe_zero(
60; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) {
61; CHECK-NEXT:    [[X0:%.*]] = add nsw i4 [[XX0]], 1
62; CHECK-NEXT:    [[X1:%.*]] = add nuw i4 [[XX1]], 1
63; CHECK-NEXT:    [[X2:%.*]] = add nuw i4 [[XX2]], 1
64; CHECK-NEXT:    [[X3:%.*]] = add nuw i4 [[XX3]], 1
65; CHECK-NEXT:    [[MUL_B:%.*]] = mul i4 [[X1]], [[X0]]
66; CHECK-NEXT:    [[MUL_A:%.*]] = mul i4 [[MUL_B]], [[X2]]
67; CHECK-NEXT:    [[MUL_C:%.*]] = mul i4 [[MUL_A]], [[X3]]
68; CHECK-NEXT:    ret i4 [[MUL_C]]
69;
70  %x0 = add nsw i4 %xx0, 1
71  %x1 = add nuw i4 %xx1, 1
72  %x2 = add nuw i4 %xx2, 1
73  %x3 = add nuw i4 %xx3, 1
74  %mul_a = mul nuw i4 %x0, %x1
75  %mul_b = mul nuw i4 %x2, %x3
76  %mul_c = mul nuw i4 %mul_a, %mul_b
77  ret i4 %mul_c
78}
79
80define i4 @re_order_mul_nsw(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) {
81; CHECK-LABEL: define i4 @re_order_mul_nsw(
82; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) {
83; CHECK-NEXT:    [[X0_NZ:%.*]] = add nuw i4 [[XX0]], 1
84; CHECK-NEXT:    [[X1_NZ:%.*]] = add nuw i4 [[XX1]], 1
85; CHECK-NEXT:    [[X2_NZ:%.*]] = add nuw i4 [[XX2]], 1
86; CHECK-NEXT:    [[X3_NZ:%.*]] = add nuw i4 [[XX3]], 1
87; CHECK-NEXT:    [[X0:%.*]] = call i4 @llvm.smax.i4(i4 [[X0_NZ]], i4 1)
88; CHECK-NEXT:    [[X1:%.*]] = call i4 @llvm.smax.i4(i4 [[X1_NZ]], i4 1)
89; CHECK-NEXT:    [[X2:%.*]] = call i4 @llvm.smax.i4(i4 [[X2_NZ]], i4 1)
90; CHECK-NEXT:    [[X3:%.*]] = call i4 @llvm.smax.i4(i4 [[X3_NZ]], i4 1)
91; CHECK-NEXT:    [[MUL_B:%.*]] = mul nsw i4 [[X1]], [[X0]]
92; CHECK-NEXT:    [[MUL_A:%.*]] = mul nsw i4 [[MUL_B]], [[X2]]
93; CHECK-NEXT:    [[MUL_C:%.*]] = mul nsw i4 [[MUL_A]], [[X3]]
94; CHECK-NEXT:    ret i4 [[MUL_C]]
95;
96  %x0_nz = add nuw i4 %xx0, 1
97  %x1_nz = add nuw i4 %xx1, 1
98  %x2_nz = add nuw i4 %xx2, 1
99  %x3_nz = add nuw i4 %xx3, 1
100  %x0 = call i4 @llvm.smax.i4(i4 %x0_nz, i4 1)
101  %x1 = call i4 @llvm.smax.i4(i4 %x1_nz, i4 1)
102  %x2 = call i4 @llvm.smax.i4(i4 %x2_nz, i4 1)
103  %x3 = call i4 @llvm.smax.i4(i4 %x3_nz, i4 1)
104  %mul_a = mul nsw i4 %x0, %x1
105  %mul_b = mul nsw i4 %x2, %x3
106  %mul_c = mul nsw i4 %mul_a, %mul_b
107  ret i4 %mul_c
108}
109
110define i4 @re_order_mul_nsw_nuw(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) {
111; CHECK-LABEL: define i4 @re_order_mul_nsw_nuw(
112; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) {
113; CHECK-NEXT:    [[X0:%.*]] = add nuw i4 [[XX0]], 1
114; CHECK-NEXT:    [[X1:%.*]] = add nuw i4 [[XX1]], 1
115; CHECK-NEXT:    [[X2:%.*]] = add nuw i4 [[XX2]], 1
116; CHECK-NEXT:    [[X3:%.*]] = add nuw i4 [[XX3]], 1
117; CHECK-NEXT:    [[MUL_B:%.*]] = mul nuw nsw i4 [[X1]], [[X0]]
118; CHECK-NEXT:    [[MUL_A:%.*]] = mul nuw nsw i4 [[MUL_B]], [[X2]]
119; CHECK-NEXT:    [[MUL_C:%.*]] = mul nuw nsw i4 [[MUL_A]], [[X3]]
120; CHECK-NEXT:    ret i4 [[MUL_C]]
121;
122  %x0 = add nuw i4 %xx0, 1
123  %x1 = add nuw i4 %xx1, 1
124  %x2 = add nuw i4 %xx2, 1
125  %x3 = add nuw i4 %xx3, 1
126  %mul_a = mul nuw nsw i4 %x0, %x1
127  %mul_b = mul nuw nsw i4 %x2, %x3
128  %mul_c = mul nuw nsw i4 %mul_a, %mul_b
129  ret i4 %mul_c
130}
131
132define i4 @re_order_mul_fail_maybe_neg(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) {
133; CHECK-LABEL: define i4 @re_order_mul_fail_maybe_neg(
134; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) {
135; CHECK-NEXT:    [[X0_NZ:%.*]] = add nuw i4 [[XX0]], 1
136; CHECK-NEXT:    [[X1_NZ:%.*]] = add nuw i4 [[XX1]], 1
137; CHECK-NEXT:    [[X2_NZ:%.*]] = add nuw i4 [[XX2]], 1
138; CHECK-NEXT:    [[X3:%.*]] = add nuw i4 [[XX3]], 1
139; CHECK-NEXT:    [[X0:%.*]] = call i4 @llvm.smax.i4(i4 [[X0_NZ]], i4 1)
140; CHECK-NEXT:    [[X1:%.*]] = call i4 @llvm.smax.i4(i4 [[X1_NZ]], i4 1)
141; CHECK-NEXT:    [[X2:%.*]] = call i4 @llvm.smax.i4(i4 [[X2_NZ]], i4 1)
142; CHECK-NEXT:    [[MUL_B:%.*]] = mul i4 [[X1]], [[X0]]
143; CHECK-NEXT:    [[MUL_A:%.*]] = mul i4 [[MUL_B]], [[X3]]
144; CHECK-NEXT:    [[MUL_C:%.*]] = mul i4 [[MUL_A]], [[X2]]
145; CHECK-NEXT:    ret i4 [[MUL_C]]
146;
147  %x0_nz = add nuw i4 %xx0, 1
148  %x1_nz = add nuw i4 %xx1, 1
149  %x2_nz = add nuw i4 %xx2, 1
150  %x3 = add nuw i4 %xx3, 1
151  %x0 = call i4 @llvm.smax.i4(i4 %x0_nz, i4 1)
152  %x1 = call i4 @llvm.smax.i4(i4 %x1_nz, i4 1)
153  %x2 = call i4 @llvm.smax.i4(i4 %x2_nz, i4 1)
154  %mul_a = mul nsw i4 %x0, %x1
155  %mul_b = mul nsw i4 %x2, %x3
156  %mul_c = mul nsw i4 %mul_a, %mul_b
157  ret i4 %mul_c
158}
159
160define i4 @re_order_mul_nsw_fail_maybe_z(i4 %xx0, i4 %xx1, i4 %xx2, i4 %xx3) {
161; CHECK-LABEL: define i4 @re_order_mul_nsw_fail_maybe_z(
162; CHECK-SAME: i4 [[XX0:%.*]], i4 [[XX1:%.*]], i4 [[XX2:%.*]], i4 [[XX3:%.*]]) {
163; CHECK-NEXT:    [[X0_NZ:%.*]] = add nuw i4 [[XX0]], 1
164; CHECK-NEXT:    [[X1_NZ:%.*]] = add nuw i4 [[XX1]], 1
165; CHECK-NEXT:    [[X2_NZ:%.*]] = add nuw i4 [[XX2]], 1
166; CHECK-NEXT:    [[X3_NZ:%.*]] = add nuw i4 [[XX3]], 1
167; CHECK-NEXT:    [[X0:%.*]] = call i4 @llvm.smax.i4(i4 [[X0_NZ]], i4 1)
168; CHECK-NEXT:    [[X1:%.*]] = call i4 @llvm.smax.i4(i4 [[X1_NZ]], i4 1)
169; CHECK-NEXT:    [[X2:%.*]] = call i4 @llvm.smax.i4(i4 [[X2_NZ]], i4 0)
170; CHECK-NEXT:    [[X3:%.*]] = call i4 @llvm.smax.i4(i4 [[X3_NZ]], i4 1)
171; CHECK-NEXT:    [[MUL_B:%.*]] = mul i4 [[X1]], [[X0]]
172; CHECK-NEXT:    [[MUL_A:%.*]] = mul i4 [[MUL_B]], [[X2]]
173; CHECK-NEXT:    [[MUL_C:%.*]] = mul i4 [[MUL_A]], [[X3]]
174; CHECK-NEXT:    ret i4 [[MUL_C]]
175;
176  %x0_nz = add nuw i4 %xx0, 1
177  %x1_nz = add nuw i4 %xx1, 1
178  %x2_nz = add nuw i4 %xx2, 1
179  %x3_nz = add nuw i4 %xx3, 1
180  %x0 = call i4 @llvm.smax.i4(i4 %x0_nz, i4 1)
181  %x1 = call i4 @llvm.smax.i4(i4 %x1_nz, i4 1)
182  %x2 = call i4 @llvm.smax.i4(i4 %x2_nz, i4 0)
183  %x3 = call i4 @llvm.smax.i4(i4 %x3_nz, i4 1)
184  %mul_a = mul nsw i4 %x0, %x1
185  %mul_b = mul nsw i4 %x2, %x3
186  %mul_c = mul nsw i4 %mul_a, %mul_b
187  ret i4 %mul_c
188}
189