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
4 ; We cannot preserve nuw flags for mul
5 define 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]]
12 %v0 = mul nuw i4 %a, %c
13 %v1 = mul nuw i4 %v0, %b
17 ; TODO: we can add nuw flags if we know all operands are non-zero.
18 define 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]]
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
36 define 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]]
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
58 define 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]]
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
80 define 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]]
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
110 define 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]]
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
132 define 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]]
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
160 define 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]]
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