1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 define i32 @uaddo_commute1(i32 %x, i32 %y, i32 %z) {
5 ; CHECK-LABEL: @uaddo_commute1(
6 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
7 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], [[Y]]
8 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[NOTY]], [[X]]
9 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[A]]
10 ; CHECK-NEXT: ret i32 [[R]]
12 %noty = xor i32 %y, -1
14 %c = icmp ugt i32 %x, %noty
15 %r = select i1 %c, i32 %z, i32 %a
19 define <2 x i32> @uaddo_commute2(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
20 ; CHECK-LABEL: @uaddo_commute2(
21 ; CHECK-NEXT: [[NOTY:%.*]] = xor <2 x i32> [[Y:%.*]], <i32 -1, i32 -1>
22 ; CHECK-NEXT: [[A:%.*]] = add <2 x i32> [[Y]], [[X:%.*]]
23 ; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> [[NOTY]], [[X]]
24 ; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C]], <2 x i32> [[Z:%.*]], <2 x i32> [[A]]
25 ; CHECK-NEXT: ret <2 x i32> [[R]]
27 %noty = xor <2 x i32> %y, <i32 -1, i32 -1>
28 %a = add <2 x i32> %y, %x
29 %c = icmp ugt <2 x i32> %x, %noty
30 %r = select <2 x i1> %c, <2 x i32> %z, <2 x i32> %a
34 define i32 @uaddo_commute3(i32 %x, i32 %y, i32 %z) {
35 ; CHECK-LABEL: @uaddo_commute3(
36 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
37 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], [[Y]]
38 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[NOTY]], [[X]]
39 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[A]]
40 ; CHECK-NEXT: ret i32 [[R]]
42 %noty = xor i32 %y, -1
44 %c = icmp ult i32 %noty, %x
45 %r = select i1 %c, i32 %z, i32 %a
49 define i32 @uaddo_commute4(i32 %x, i32 %y, i32 %z) {
50 ; CHECK-LABEL: @uaddo_commute4(
51 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
52 ; CHECK-NEXT: [[A:%.*]] = add i32 [[Y]], [[X:%.*]]
53 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[NOTY]], [[X]]
54 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[A]]
55 ; CHECK-NEXT: ret i32 [[R]]
57 %noty = xor i32 %y, -1
59 %c = icmp ult i32 %noty, %x
60 %r = select i1 %c, i32 %z, i32 %a
64 define i32 @uaddo_commute5(i32 %x, i32 %y, i32 %z) {
65 ; CHECK-LABEL: @uaddo_commute5(
66 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
67 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], [[Y]]
68 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[NOTY]], [[X]]
69 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 [[Z:%.*]]
70 ; CHECK-NEXT: ret i32 [[R]]
72 %noty = xor i32 %y, -1
74 %c = icmp ugt i32 %x, %noty
75 %r = select i1 %c, i32 %a, i32 %z
79 define i32 @uaddo_commute6(i32 %x, i32 %y, i32 %z) {
80 ; CHECK-LABEL: @uaddo_commute6(
81 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
82 ; CHECK-NEXT: [[A:%.*]] = add i32 [[Y]], [[X:%.*]]
83 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[NOTY]], [[X]]
84 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 [[Z:%.*]]
85 ; CHECK-NEXT: ret i32 [[R]]
87 %noty = xor i32 %y, -1
89 %c = icmp ugt i32 %x, %noty
90 %r = select i1 %c, i32 %a, i32 %z
94 define i32 @uaddo_commute7(i32 %x, i32 %y, i32 %z) {
95 ; CHECK-LABEL: @uaddo_commute7(
96 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
97 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], [[Y]]
98 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[NOTY]], [[X]]
99 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 [[Z:%.*]]
100 ; CHECK-NEXT: ret i32 [[R]]
102 %noty = xor i32 %y, -1
104 %c = icmp ult i32 %noty, %x
105 %r = select i1 %c, i32 %a, i32 %z
109 define i32 @uaddo_commute8(i32 %x, i32 %y, i32 %z) {
110 ; CHECK-LABEL: @uaddo_commute8(
111 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
112 ; CHECK-NEXT: [[A:%.*]] = add i32 [[Y]], [[X:%.*]]
113 ; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[NOTY]], [[X]]
114 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[A]], i32 [[Z:%.*]]
115 ; CHECK-NEXT: ret i32 [[R]]
117 %noty = xor i32 %y, -1
119 %c = icmp ult i32 %noty, %x
120 %r = select i1 %c, i32 %a, i32 %z
124 define i32 @uaddo_wrong_pred1(i32 %x, i32 %y, i32 %z) {
125 ; CHECK-LABEL: @uaddo_wrong_pred1(
126 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
127 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], [[Y]]
128 ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[NOTY]], [[X]]
129 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C]], i32 [[Z:%.*]], i32 [[A]]
130 ; CHECK-NEXT: ret i32 [[R]]
132 %noty = xor i32 %y, -1
134 %c = icmp ult i32 %x, %noty
135 %r = select i1 %c, i32 %z, i32 %a
139 define i32 @uaddo_wrong_pred2(i32 %x, i32 %y, i32 %z) {
140 ; CHECK-LABEL: @uaddo_wrong_pred2(
141 ; CHECK-NEXT: [[NOTY:%.*]] = xor i32 [[Y:%.*]], -1
142 ; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], [[Y]]
143 ; CHECK-NEXT: [[C_NOT:%.*]] = icmp ugt i32 [[NOTY]], [[X]]
144 ; CHECK-NEXT: [[R:%.*]] = select i1 [[C_NOT]], i32 [[A]], i32 [[Z:%.*]]
145 ; CHECK-NEXT: ret i32 [[R]]
147 %noty = xor i32 %y, -1
149 %c = icmp uge i32 %x, %noty
150 %r = select i1 %c, i32 %z, i32 %a
154 ; icmp canonicalization should be consistent for these cases.
155 ; Either the compare depends on the sum or not.
157 define i1 @uaddo_1(i8 %x, ptr %p) {
158 ; CHECK-LABEL: @uaddo_1(
159 ; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], 1
160 ; CHECK-NEXT: store i8 [[A]], ptr [[P:%.*]], align 1
161 ; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[A]], 0
162 ; CHECK-NEXT: ret i1 [[C]]
166 %c = icmp ult i8 %a, 1
170 define i1 @uaddo_neg1(i8 %x, ptr %p) {
171 ; CHECK-LABEL: @uaddo_neg1(
172 ; CHECK-NEXT: [[A:%.*]] = add i8 [[X:%.*]], -1
173 ; CHECK-NEXT: store i8 [[A]], ptr [[P:%.*]], align 1
174 ; CHECK-NEXT: [[C:%.*]] = icmp ne i8 [[X]], 0
175 ; CHECK-NEXT: ret i1 [[C]]
179 %c = icmp ne i8 %a, -1