1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2 ; RUN: opt -S -instcombine < %s | FileCheck %s 3 4 define <2 x i32> @umin_of_nots(<2 x i32> %x, <2 x i32> %y) { 5 ; CHECK-LABEL: @umin_of_nots( 6 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt <2 x i32> [[X:%.*]], [[Y:%.*]] 7 ; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> [[Y]] 8 ; CHECK-NEXT: [[MIN:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 -1> 9 ; CHECK-NEXT: ret <2 x i32> [[MIN]] 10 ; 11 %notx = xor <2 x i32> %x, <i32 -1, i32 -1> 12 %noty = xor <2 x i32> %y, <i32 -1, i32 -1> 13 %cmp = icmp ult <2 x i32> %notx, %noty 14 %min = select <2 x i1> %cmp, <2 x i32> %notx, <2 x i32> %noty 15 ret <2 x i32> %min 16 } 17 18 define <2 x i32> @smin_of_nots(<2 x i32> %x, <2 x i32> %y) { 19 ; CHECK-LABEL: @smin_of_nots( 20 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], [[Y:%.*]] 21 ; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> [[Y]] 22 ; CHECK-NEXT: [[MIN:%.*]] = xor <2 x i32> [[TMP2]], <i32 -1, i32 -1> 23 ; CHECK-NEXT: ret <2 x i32> [[MIN]] 24 ; 25 %notx = xor <2 x i32> %x, <i32 -1, i32 -1> 26 %noty = xor <2 x i32> %y, <i32 -1, i32 -1> 27 %cmp = icmp sle <2 x i32> %notx, %noty 28 %min = select <2 x i1> %cmp, <2 x i32> %notx, <2 x i32> %noty 29 ret <2 x i32> %min 30 } 31 32 define i32 @compute_min_2(i32 %x, i32 %y) { 33 ; CHECK-LABEL: @compute_min_2( 34 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 35 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[Y]] 36 ; CHECK-NEXT: ret i32 [[TMP2]] 37 ; 38 %not_x = sub i32 -1, %x 39 %not_y = sub i32 -1, %y 40 %cmp = icmp sgt i32 %not_x, %not_y 41 %not_min = select i1 %cmp, i32 %not_x, i32 %not_y 42 %min = sub i32 -1, %not_min 43 ret i32 %min 44 } 45 46 declare void @extra_use(i8) 47 define i8 @umin_not_1_extra_use(i8 %x, i8 %y) { 48 ; CHECK-LABEL: @umin_not_1_extra_use( 49 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 50 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X]], [[Y:%.*]] 51 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Y]] 52 ; CHECK-NEXT: [[MINXY:%.*]] = xor i8 [[TMP2]], -1 53 ; CHECK-NEXT: call void @extra_use(i8 [[NX]]) 54 ; CHECK-NEXT: ret i8 [[MINXY]] 55 ; 56 %nx = xor i8 %x, -1 57 %ny = xor i8 %y, -1 58 %cmpxy = icmp ult i8 %nx, %ny 59 %minxy = select i1 %cmpxy, i8 %nx, i8 %ny 60 call void @extra_use(i8 %nx) 61 ret i8 %minxy 62 } 63 64 define i8 @umin_not_2_extra_use(i8 %x, i8 %y) { 65 ; CHECK-LABEL: @umin_not_2_extra_use( 66 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 67 ; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1 68 ; CHECK-NEXT: [[CMPXY:%.*]] = icmp ult i8 [[NX]], [[NY]] 69 ; CHECK-NEXT: [[MINXY:%.*]] = select i1 [[CMPXY]], i8 [[NX]], i8 [[NY]] 70 ; CHECK-NEXT: call void @extra_use(i8 [[NX]]) 71 ; CHECK-NEXT: call void @extra_use(i8 [[NY]]) 72 ; CHECK-NEXT: ret i8 [[MINXY]] 73 ; 74 %nx = xor i8 %x, -1 75 %ny = xor i8 %y, -1 76 %cmpxy = icmp ult i8 %nx, %ny 77 %minxy = select i1 %cmpxy, i8 %nx, i8 %ny 78 call void @extra_use(i8 %nx) 79 call void @extra_use(i8 %ny) 80 ret i8 %minxy 81 } 82 83 ; PR35834 - https://bugs.llvm.org/show_bug.cgi?id=35834 84 85 define i8 @umin3_not(i8 %x, i8 %y, i8 %z) { 86 ; CHECK-LABEL: @umin3_not( 87 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X:%.*]], [[Z:%.*]] 88 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Z]] 89 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[Y:%.*]] 90 ; CHECK-NEXT: [[R_V:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[Y]] 91 ; CHECK-NEXT: [[R:%.*]] = xor i8 [[R_V]], -1 92 ; CHECK-NEXT: ret i8 [[R]] 93 ; 94 %nx = xor i8 %x, -1 95 %ny = xor i8 %y, -1 96 %nz = xor i8 %z, -1 97 %cmpyx = icmp ult i8 %y, %x 98 %cmpxz = icmp ult i8 %nx, %nz 99 %minxz = select i1 %cmpxz, i8 %nx, i8 %nz 100 %cmpyz = icmp ult i8 %ny, %nz 101 %minyz = select i1 %cmpyz, i8 %ny, i8 %nz 102 %r = select i1 %cmpyx, i8 %minxz, i8 %minyz 103 ret i8 %r 104 } 105 106 ; PR35875 - https://bugs.llvm.org/show_bug.cgi?id=35875 107 108 define i8 @umin3_not_more_uses(i8 %x, i8 %y, i8 %z) { 109 ; CHECK-LABEL: @umin3_not_more_uses( 110 ; CHECK-NEXT: [[NX:%.*]] = xor i8 [[X:%.*]], -1 111 ; CHECK-NEXT: [[NY:%.*]] = xor i8 [[Y:%.*]], -1 112 ; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[X]], [[Z:%.*]] 113 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[Z]] 114 ; CHECK-NEXT: [[TMP3:%.*]] = icmp ugt i8 [[TMP2]], [[Y]] 115 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i8 [[TMP2]], i8 [[Y]] 116 ; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP4]], -1 117 ; CHECK-NEXT: call void @extra_use(i8 [[NX]]) 118 ; CHECK-NEXT: call void @extra_use(i8 [[NY]]) 119 ; CHECK-NEXT: ret i8 [[R]] 120 ; 121 %nx = xor i8 %x, -1 122 %ny = xor i8 %y, -1 123 %nz = xor i8 %z, -1 124 %cmpxz = icmp ult i8 %nx, %nz 125 %minxz = select i1 %cmpxz, i8 %nx, i8 %nz 126 %cmpyz = icmp ult i8 %ny, %nz 127 %minyz = select i1 %cmpyz, i8 %ny, i8 %nz 128 %cmpyx = icmp ult i8 %y, %x 129 %r = select i1 %cmpyx, i8 %minxz, i8 %minyz 130 call void @extra_use(i8 %nx) 131 call void @extra_use(i8 %ny) 132 ret i8 %r 133 } 134 135 declare void @use8(i8) 136 137 define i8 @umin3_not_all_ops_extra_uses(i8 %x, i8 %y, i8 %z) { 138 ; CHECK-LABEL: @umin3_not_all_ops_extra_uses( 139 ; CHECK-NEXT: [[XN:%.*]] = xor i8 [[X:%.*]], -1 140 ; CHECK-NEXT: [[YN:%.*]] = xor i8 [[Y:%.*]], -1 141 ; CHECK-NEXT: [[ZN:%.*]] = xor i8 [[Z:%.*]], -1 142 ; CHECK-NEXT: [[CMPXZ:%.*]] = icmp ult i8 [[XN]], [[ZN]] 143 ; CHECK-NEXT: [[MINXZ:%.*]] = select i1 [[CMPXZ]], i8 [[XN]], i8 [[ZN]] 144 ; CHECK-NEXT: [[CMPXYZ:%.*]] = icmp ult i8 [[MINXZ]], [[YN]] 145 ; CHECK-NEXT: [[MINXYZ:%.*]] = select i1 [[CMPXYZ]], i8 [[MINXZ]], i8 [[YN]] 146 ; CHECK-NEXT: call void @use8(i8 [[XN]]) 147 ; CHECK-NEXT: call void @use8(i8 [[YN]]) 148 ; CHECK-NEXT: call void @use8(i8 [[ZN]]) 149 ; CHECK-NEXT: ret i8 [[MINXYZ]] 150 ; 151 %xn = xor i8 %x, -1 152 %yn = xor i8 %y, -1 153 %zn = xor i8 %z, -1 154 %cmpxz = icmp ult i8 %xn, %zn 155 %minxz = select i1 %cmpxz, i8 %xn, i8 %zn 156 %cmpxyz = icmp ult i8 %minxz, %yn 157 %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn 158 call void @use8(i8 %xn) 159 call void @use8(i8 %yn) 160 call void @use8(i8 %zn) 161 ret i8 %minxyz 162 } 163 164 define void @umin3_not_all_ops_extra_uses_invert_subs(i8 %x, i8 %y, i8 %z) { 165 ; CHECK-LABEL: @umin3_not_all_ops_extra_uses_invert_subs( 166 ; CHECK-NEXT: [[XN:%.*]] = xor i8 [[X:%.*]], -1 167 ; CHECK-NEXT: [[YN:%.*]] = xor i8 [[Y:%.*]], -1 168 ; CHECK-NEXT: [[ZN:%.*]] = xor i8 [[Z:%.*]], -1 169 ; CHECK-NEXT: [[CMPXZ:%.*]] = icmp ult i8 [[XN]], [[ZN]] 170 ; CHECK-NEXT: [[MINXZ:%.*]] = select i1 [[CMPXZ]], i8 [[XN]], i8 [[ZN]] 171 ; CHECK-NEXT: [[CMPXYZ:%.*]] = icmp ult i8 [[MINXZ]], [[YN]] 172 ; CHECK-NEXT: [[MINXYZ:%.*]] = select i1 [[CMPXYZ]], i8 [[MINXZ]], i8 [[YN]] 173 ; CHECK-NEXT: [[XMIN:%.*]] = sub i8 [[XN]], [[MINXYZ]] 174 ; CHECK-NEXT: [[YMIN:%.*]] = sub i8 [[YN]], [[MINXYZ]] 175 ; CHECK-NEXT: [[ZMIN:%.*]] = sub i8 [[ZN]], [[MINXYZ]] 176 ; CHECK-NEXT: call void @use8(i8 [[MINXYZ]]) 177 ; CHECK-NEXT: call void @use8(i8 [[XMIN]]) 178 ; CHECK-NEXT: call void @use8(i8 [[YMIN]]) 179 ; CHECK-NEXT: call void @use8(i8 [[ZMIN]]) 180 ; CHECK-NEXT: ret void 181 ; 182 %xn = xor i8 %x, -1 183 %yn = xor i8 %y, -1 184 %zn = xor i8 %z, -1 185 %cmpxz = icmp ult i8 %xn, %zn 186 %minxz = select i1 %cmpxz, i8 %xn, i8 %zn 187 %cmpxyz = icmp ult i8 %minxz, %yn 188 %minxyz = select i1 %cmpxyz, i8 %minxz, i8 %yn 189 %xmin = sub i8 %xn, %minxyz 190 %ymin = sub i8 %yn, %minxyz 191 %zmin = sub i8 %zn, %minxyz 192 call void @use8(i8 %minxyz) 193 call void @use8(i8 %xmin) 194 call void @use8(i8 %ymin) 195 call void @use8(i8 %zmin) 196 ret void 197 } 198 199 define i32 @compute_min_3(i32 %x, i32 %y, i32 %z) { 200 ; CHECK-LABEL: @compute_min_3( 201 ; CHECK-NEXT: [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]] 202 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 [[Y]] 203 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], [[Z:%.*]] 204 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 [[Z]] 205 ; CHECK-NEXT: ret i32 [[TMP4]] 206 ; 207 %not_x = sub i32 -1, %x 208 %not_y = sub i32 -1, %y 209 %not_z = sub i32 -1, %z 210 %cmp_1 = icmp sgt i32 %not_x, %not_y 211 %not_min_1 = select i1 %cmp_1, i32 %not_x, i32 %not_y 212 %cmp_2 = icmp sgt i32 %not_min_1, %not_z 213 %not_min_2 = select i1 %cmp_2, i32 %not_min_1, i32 %not_z 214 %min = sub i32 -1, %not_min_2 215 ret i32 %min 216 } 217 218 ; Don't increase the critical path by moving the 'not' op after the 'select'. 219 220 define i32 @compute_min_arithmetic(i32 %x, i32 %y) { 221 ; CHECK-LABEL: @compute_min_arithmetic( 222 ; CHECK-NEXT: [[NOT_VALUE:%.*]] = sub i32 3, [[X:%.*]] 223 ; CHECK-NEXT: [[NOT_Y:%.*]] = xor i32 [[Y:%.*]], -1 224 ; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[NOT_VALUE]], [[NOT_Y]] 225 ; CHECK-NEXT: [[NOT_MIN:%.*]] = select i1 [[CMP]], i32 [[NOT_VALUE]], i32 [[NOT_Y]] 226 ; CHECK-NEXT: ret i32 [[NOT_MIN]] 227 ; 228 %not_value = sub i32 3, %x 229 %not_y = sub i32 -1, %y 230 %cmp = icmp sgt i32 %not_value, %not_y 231 %not_min = select i1 %cmp, i32 %not_value, i32 %not_y 232 ret i32 %not_min 233 } 234 235 declare void @fake_use(i32) 236 237 define i32 @compute_min_pessimization(i32 %x, i32 %y) { 238 ; CHECK-LABEL: @compute_min_pessimization( 239 ; CHECK-NEXT: [[NOT_VALUE:%.*]] = sub i32 3, [[X:%.*]] 240 ; CHECK-NEXT: call void @fake_use(i32 [[NOT_VALUE]]) 241 ; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[X]], -4 242 ; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], [[Y:%.*]] 243 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[TMP2]], i32 [[Y]], i32 [[TMP1]] 244 ; CHECK-NEXT: ret i32 [[MIN]] 245 ; 246 %not_value = sub i32 3, %x 247 call void @fake_use(i32 %not_value) 248 %not_y = sub i32 -1, %y 249 %cmp = icmp sgt i32 %not_value, %not_y 250 %not_min = select i1 %cmp, i32 %not_value, i32 %not_y 251 %min = sub i32 -1, %not_min 252 ret i32 %min 253 } 254 255 define i32 @max_of_nots(i32 %x, i32 %y) { 256 ; CHECK-LABEL: @max_of_nots( 257 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[Y:%.*]], 0 258 ; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[Y]], i32 0 259 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[TMP2]], [[X:%.*]] 260 ; CHECK-NEXT: [[TMP4:%.*]] = select i1 [[TMP3]], i32 [[TMP2]], i32 [[X]] 261 ; CHECK-NEXT: [[TMP5:%.*]] = xor i32 [[TMP4]], -1 262 ; CHECK-NEXT: ret i32 [[TMP5]] 263 ; 264 %c0 = icmp sgt i32 %y, 0 265 %xor_y = xor i32 %y, -1 266 %s0 = select i1 %c0, i32 %xor_y, i32 -1 267 %xor_x = xor i32 %x, -1 268 %c1 = icmp slt i32 %s0, %xor_x 269 %smax96 = select i1 %c1, i32 %xor_x, i32 %s0 270 ret i32 %smax96 271 } 272 273 ; negative test case (i.e. can not simplify) : ABS(MIN(NOT x,y)) 274 define i32 @abs_of_min_of_not(i32 %x, i32 %y) { 275 ; CHECK-LABEL: @abs_of_min_of_not( 276 ; CHECK-NEXT: [[XORD:%.*]] = xor i32 [[X:%.*]], -1 277 ; CHECK-NEXT: [[YADD:%.*]] = add i32 [[Y:%.*]], 2 278 ; CHECK-NEXT: [[COND_I:%.*]] = icmp slt i32 [[YADD]], [[XORD]] 279 ; CHECK-NEXT: [[MIN:%.*]] = select i1 [[COND_I]], i32 [[YADD]], i32 [[XORD]] 280 ; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[MIN]], 0 281 ; CHECK-NEXT: [[SUB:%.*]] = sub i32 0, [[MIN]] 282 ; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP2]], i32 [[SUB]], i32 [[MIN]] 283 ; CHECK-NEXT: ret i32 [[ABS]] 284 ; 285 286 %xord = xor i32 %x, -1 287 %yadd = add i32 %y, 2 288 %cond.i = icmp sge i32 %yadd, %xord 289 %min = select i1 %cond.i, i32 %xord, i32 %yadd 290 %cmp2 = icmp sgt i32 %min, -1 291 %sub = sub i32 0, %min 292 %abs = select i1 %cmp2, i32 %min, i32 %sub 293 ret i32 %abs 294 } 295 296 define <2 x i32> @max_of_nots_vec(<2 x i32> %x, <2 x i32> %y) { 297 ; CHECK-LABEL: @max_of_nots_vec( 298 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i32> [[Y:%.*]], zeroinitializer 299 ; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[Y]], <2 x i32> zeroinitializer 300 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt <2 x i32> [[TMP2]], [[X:%.*]] 301 ; CHECK-NEXT: [[TMP4:%.*]] = select <2 x i1> [[TMP3]], <2 x i32> [[TMP2]], <2 x i32> [[X]] 302 ; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i32> [[TMP4]], <i32 -1, i32 -1> 303 ; CHECK-NEXT: ret <2 x i32> [[TMP5]] 304 ; 305 %c0 = icmp sgt <2 x i32> %y, zeroinitializer 306 %xor_y = xor <2 x i32> %y, <i32 -1, i32 -1> 307 %s0 = select <2 x i1> %c0, <2 x i32> %xor_y, <2 x i32> <i32 -1, i32 -1> 308 %xor_x = xor <2 x i32> %x, <i32 -1, i32 -1> 309 %c1 = icmp slt <2 x i32> %s0, %xor_x 310 %smax96 = select <2 x i1> %c1, <2 x i32> %xor_x, <2 x i32> %s0 311 ret <2 x i32> %smax96 312 } 313 314 define <2 x i37> @max_of_nots_weird_type_vec(<2 x i37> %x, <2 x i37> %y) { 315 ; CHECK-LABEL: @max_of_nots_weird_type_vec( 316 ; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i37> [[Y:%.*]], zeroinitializer 317 ; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i37> [[Y]], <2 x i37> zeroinitializer 318 ; CHECK-NEXT: [[TMP3:%.*]] = icmp slt <2 x i37> [[TMP2]], [[X:%.*]] 319 ; CHECK-NEXT: [[TMP4:%.*]] = select <2 x i1> [[TMP3]], <2 x i37> [[TMP2]], <2 x i37> [[X]] 320 ; CHECK-NEXT: [[TMP5:%.*]] = xor <2 x i37> [[TMP4]], <i37 -1, i37 -1> 321 ; CHECK-NEXT: ret <2 x i37> [[TMP5]] 322 ; 323 %c0 = icmp sgt <2 x i37> %y, zeroinitializer 324 %xor_y = xor <2 x i37> %y, <i37 -1, i37 -1> 325 %s0 = select <2 x i1> %c0, <2 x i37> %xor_y, <2 x i37> <i37 -1, i37 -1> 326 %xor_x = xor <2 x i37> %x, <i37 -1, i37 -1> 327 %c1 = icmp slt <2 x i37> %s0, %xor_x 328 %smax96 = select <2 x i1> %c1, <2 x i37> %xor_x, <2 x i37> %s0 329 ret <2 x i37> %smax96 330 } 331 332 ; max(min(%a, -1), -1) == -1 333 define i32 @max_of_min(i32 %a) { 334 ; CHECK-LABEL: @max_of_min( 335 ; CHECK-NEXT: ret i32 -1 336 ; 337 %not_a = xor i32 %a, -1 338 %c0 = icmp sgt i32 %a, 0 339 %s0 = select i1 %c0, i32 %not_a, i32 -1 340 %c1 = icmp sgt i32 %s0, -1 341 %s1 = select i1 %c1, i32 %s0, i32 -1 342 ret i32 %s1 343 } 344 345 ; max(min(%a, -1), -1) == -1 (swap predicate and select ops) 346 define i32 @max_of_min_swap(i32 %a) { 347 ; CHECK-LABEL: @max_of_min_swap( 348 ; CHECK-NEXT: ret i32 -1 349 ; 350 %not_a = xor i32 %a, -1 351 %c0 = icmp slt i32 %a, 0 352 %s0 = select i1 %c0, i32 -1, i32 %not_a 353 %c1 = icmp sgt i32 %s0, -1 354 %s1 = select i1 %c1, i32 %s0, i32 -1 355 ret i32 %s1 356 } 357 358 ; min(max(%a, -1), -1) == -1 359 define i32 @min_of_max(i32 %a) { 360 ; CHECK-LABEL: @min_of_max( 361 ; CHECK-NEXT: ret i32 -1 362 ; 363 %not_a = xor i32 %a, -1 364 %c0 = icmp slt i32 %a, 0 365 %s0 = select i1 %c0, i32 %not_a, i32 -1 366 %c1 = icmp slt i32 %s0, -1 367 %s1 = select i1 %c1, i32 %s0, i32 -1 368 ret i32 %s1 369 } 370 371 ; min(max(%a, -1), -1) == -1 (swap predicate and select ops) 372 define i32 @min_of_max_swap(i32 %a) { 373 ; CHECK-LABEL: @min_of_max_swap( 374 ; CHECK-NEXT: ret i32 -1 375 ; 376 %not_a = xor i32 %a, -1 377 %c0 = icmp sgt i32 %a, 0 378 %s0 = select i1 %c0, i32 -1, i32 %not_a 379 %c1 = icmp slt i32 %s0, -1 380 %s1 = select i1 %c1, i32 %s0, i32 -1 381 ret i32 %s1 382 } 383 384 define <2 x i32> @max_of_min_vec(<2 x i32> %a) { 385 ; CHECK-LABEL: @max_of_min_vec( 386 ; CHECK-NEXT: ret <2 x i32> <i32 -1, i32 -1> 387 ; 388 %not_a = xor <2 x i32> %a, <i32 -1, i32 -1> 389 %c0 = icmp sgt <2 x i32> %a, zeroinitializer 390 %s0 = select <2 x i1> %c0, <2 x i32> %not_a, <2 x i32> <i32 -1, i32 -1> 391 %c1 = icmp sgt <2 x i32> %s0, <i32 -1, i32 -1> 392 %s1 = select <2 x i1> %c1, <2 x i32> %s0, <2 x i32> <i32 -1, i32 -1> 393 ret <2 x i32> %s1 394 } 395 396