1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4; If we have a umax feeding an unsigned or equality icmp that shares an 5; operand with the umax, the compare should always be folded. 6; Test all 4 foldable predicates (eq,ne,ugt,ule) * 4 commutation 7; possibilities for each predicate. Note that folds to true/false 8; (predicate = uge/ult) or folds to an existing instruction should be 9; handled by InstSimplify. 10 11; umax(X, Y) == X --> X >= Y 12 13define i1 @eq_umax1(i32 %x, i32 %y) { 14; CHECK-LABEL: @eq_umax1( 15; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 16; CHECK-NEXT: ret i1 [[CMP2]] 17; 18 %cmp1 = icmp ugt i32 %x, %y 19 %sel = select i1 %cmp1, i32 %x, i32 %y 20 %cmp2 = icmp eq i32 %sel, %x 21 ret i1 %cmp2 22} 23 24; Commute max operands. 25 26define i1 @eq_umax2(i32 %x, i32 %y) { 27; CHECK-LABEL: @eq_umax2( 28; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 29; CHECK-NEXT: ret i1 [[CMP2]] 30; 31 %cmp1 = icmp ugt i32 %y, %x 32 %sel = select i1 %cmp1, i32 %y, i32 %x 33 %cmp2 = icmp eq i32 %sel, %x 34 ret i1 %cmp2 35} 36 37; Disguise the icmp predicate by commuting the max op to the RHS. 38 39define i1 @eq_umax3(i32 %a, i32 %y) { 40; CHECK-LABEL: @eq_umax3( 41; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 42; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[Y:%.*]] 43; CHECK-NEXT: ret i1 [[CMP2]] 44; 45 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 46 %cmp1 = icmp ugt i32 %x, %y 47 %sel = select i1 %cmp1, i32 %x, i32 %y 48 %cmp2 = icmp eq i32 %x, %sel 49 ret i1 %cmp2 50} 51 52; Commute max operands. 53 54define i1 @eq_umax4(i32 %a, i32 %y) { 55; CHECK-LABEL: @eq_umax4( 56; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 57; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[X]], [[Y:%.*]] 58; CHECK-NEXT: ret i1 [[CMP2]] 59; 60 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 61 %cmp1 = icmp ugt i32 %y, %x 62 %sel = select i1 %cmp1, i32 %y, i32 %x 63 %cmp2 = icmp eq i32 %x, %sel 64 ret i1 %cmp2 65} 66 67; umax(X, Y) <= X --> Y <= X 68 69define i1 @ule_umax1(i32 %x, i32 %y) { 70; CHECK-LABEL: @ule_umax1( 71; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[Y:%.*]], [[X:%.*]] 72; CHECK-NEXT: ret i1 [[CMP2]] 73; 74 %cmp1 = icmp ugt i32 %x, %y 75 %sel = select i1 %cmp1, i32 %x, i32 %y 76 %cmp2 = icmp ule i32 %sel, %x 77 ret i1 %cmp2 78} 79 80; Commute max operands. 81 82define i1 @ule_umax2(i32 %x, i32 %y) { 83; CHECK-LABEL: @ule_umax2( 84; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[Y:%.*]], [[X:%.*]] 85; CHECK-NEXT: ret i1 [[CMP2]] 86; 87 %cmp1 = icmp ugt i32 %y, %x 88 %sel = select i1 %cmp1, i32 %y, i32 %x 89 %cmp2 = icmp ule i32 %sel, %x 90 ret i1 %cmp2 91} 92 93; Disguise the icmp predicate by commuting the max op to the RHS. 94 95define i1 @ule_umax3(i32 %a, i32 %y) { 96; CHECK-LABEL: @ule_umax3( 97; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 98; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[Y:%.*]], [[X]] 99; CHECK-NEXT: ret i1 [[CMP2]] 100; 101 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 102 %cmp1 = icmp ugt i32 %x, %y 103 %sel = select i1 %cmp1, i32 %x, i32 %y 104 %cmp2 = icmp uge i32 %x, %sel 105 ret i1 %cmp2 106} 107 108; Commute max operands. 109 110define i1 @ule_umax4(i32 %a, i32 %y) { 111; CHECK-LABEL: @ule_umax4( 112; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 113; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[Y:%.*]], [[X]] 114; CHECK-NEXT: ret i1 [[CMP2]] 115; 116 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 117 %cmp1 = icmp ugt i32 %y, %x 118 %sel = select i1 %cmp1, i32 %y, i32 %x 119 %cmp2 = icmp uge i32 %x, %sel 120 ret i1 %cmp2 121} 122 123; umax(X, Y) != X --> X < Y 124 125define i1 @ne_umax1(i32 %x, i32 %y) { 126; CHECK-LABEL: @ne_umax1( 127; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 128; CHECK-NEXT: ret i1 [[CMP2]] 129; 130 %cmp1 = icmp ugt i32 %x, %y 131 %sel = select i1 %cmp1, i32 %x, i32 %y 132 %cmp2 = icmp ne i32 %sel, %x 133 ret i1 %cmp2 134} 135 136; Commute max operands. 137 138define i1 @ne_umax2(i32 %x, i32 %y) { 139; CHECK-LABEL: @ne_umax2( 140; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 141; CHECK-NEXT: ret i1 [[CMP2]] 142; 143 %cmp1 = icmp ugt i32 %y, %x 144 %sel = select i1 %cmp1, i32 %y, i32 %x 145 %cmp2 = icmp ne i32 %sel, %x 146 ret i1 %cmp2 147} 148 149; Disguise the icmp predicate by commuting the max op to the RHS. 150 151define i1 @ne_umax3(i32 %a, i32 %y) { 152; CHECK-LABEL: @ne_umax3( 153; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 154; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y:%.*]] 155; CHECK-NEXT: ret i1 [[CMP2]] 156; 157 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 158 %cmp1 = icmp ugt i32 %x, %y 159 %sel = select i1 %cmp1, i32 %x, i32 %y 160 %cmp2 = icmp ne i32 %x, %sel 161 ret i1 %cmp2 162} 163 164; Commute max operands. 165 166define i1 @ne_umax4(i32 %a, i32 %y) { 167; CHECK-LABEL: @ne_umax4( 168; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 169; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[X]], [[Y:%.*]] 170; CHECK-NEXT: ret i1 [[CMP2]] 171; 172 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 173 %cmp1 = icmp ugt i32 %y, %x 174 %sel = select i1 %cmp1, i32 %y, i32 %x 175 %cmp2 = icmp ne i32 %x, %sel 176 ret i1 %cmp2 177} 178 179; umax(X, Y) > X --> Y > X 180 181define i1 @ugt_umax1(i32 %x, i32 %y) { 182; CHECK-LABEL: @ugt_umax1( 183; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]] 184; CHECK-NEXT: ret i1 [[CMP2]] 185; 186 %cmp1 = icmp ugt i32 %x, %y 187 %sel = select i1 %cmp1, i32 %x, i32 %y 188 %cmp2 = icmp ugt i32 %sel, %x 189 ret i1 %cmp2 190} 191 192; Commute max operands. 193 194define i1 @ugt_umax2(i32 %x, i32 %y) { 195; CHECK-LABEL: @ugt_umax2( 196; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X:%.*]] 197; CHECK-NEXT: ret i1 [[CMP2]] 198; 199 %cmp1 = icmp ugt i32 %y, %x 200 %sel = select i1 %cmp1, i32 %y, i32 %x 201 %cmp2 = icmp ugt i32 %sel, %x 202 ret i1 %cmp2 203} 204 205; Disguise the icmp predicate by commuting the max op to the RHS. 206 207define i1 @ugt_umax3(i32 %a, i32 %y) { 208; CHECK-LABEL: @ugt_umax3( 209; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 210; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X]] 211; CHECK-NEXT: ret i1 [[CMP2]] 212; 213 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 214 %cmp1 = icmp ugt i32 %x, %y 215 %sel = select i1 %cmp1, i32 %x, i32 %y 216 %cmp2 = icmp ult i32 %x, %sel 217 ret i1 %cmp2 218} 219 220; Commute max operands. 221 222define i1 @ugt_umax4(i32 %a, i32 %y) { 223; CHECK-LABEL: @ugt_umax4( 224; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3 225; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[Y:%.*]], [[X]] 226; CHECK-NEXT: ret i1 [[CMP2]] 227; 228 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 229 %cmp1 = icmp ugt i32 %y, %x 230 %sel = select i1 %cmp1, i32 %y, i32 %x 231 %cmp2 = icmp ult i32 %x, %sel 232 ret i1 %cmp2 233} 234 235declare void @use(i1 %c) 236 237define void @eq_umax_contextual(i32 %x, i32 %y, i32 %z) { 238; CHECK-LABEL: @eq_umax_contextual( 239; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Z:%.*]] 240; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]] 241; CHECK: if: 242; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]]) 243; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 244; CHECK-NEXT: call void @use(i1 [[CMP1]]) 245; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 246; CHECK-NEXT: call void @use(i1 [[CMP2]]) 247; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 248; CHECK-NEXT: call void @use(i1 [[CMP3]]) 249; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 250; CHECK-NEXT: call void @use(i1 [[CMP4]]) 251; CHECK-NEXT: call void @use(i1 false) 252; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]] 253; CHECK-NEXT: call void @use(i1 [[CMP6]]) 254; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]] 255; CHECK-NEXT: call void @use(i1 [[CMP7]]) 256; CHECK-NEXT: call void @use(i1 true) 257; CHECK-NEXT: [[CMP9:%.*]] = icmp uge i32 [[X]], [[Y]] 258; CHECK-NEXT: call void @use(i1 [[CMP9]]) 259; CHECK-NEXT: [[CMP10:%.*]] = icmp ult i32 [[X]], [[Y]] 260; CHECK-NEXT: call void @use(i1 [[CMP10]]) 261; CHECK-NEXT: ret void 262; CHECK: end: 263; CHECK-NEXT: ret void 264; 265 %cmp = icmp eq i32 %x, %z 266 br i1 %cmp, label %if, label %end 267if: 268 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y) 269 %cmp1 = icmp slt i32 %cond, %z 270 call void @use(i1 %cmp1) 271 %cmp2 = icmp sle i32 %cond, %z 272 call void @use(i1 %cmp2) 273 %cmp3 = icmp sgt i32 %cond, %z 274 call void @use(i1 %cmp3) 275 %cmp4 = icmp sge i32 %cond, %z 276 call void @use(i1 %cmp4) 277 %cmp5 = icmp ult i32 %cond, %z 278 call void @use(i1 %cmp5) 279 %cmp6 = icmp ule i32 %cond, %z 280 call void @use(i1 %cmp6) 281 %cmp7 = icmp ugt i32 %cond, %z 282 call void @use(i1 %cmp7) 283 %cmp8 = icmp uge i32 %cond, %z 284 call void @use(i1 %cmp8) 285 %cmp9 = icmp eq i32 %cond, %z 286 call void @use(i1 %cmp9) 287 %cmp10 = icmp ne i32 %cond, %z 288 call void @use(i1 %cmp10) 289 ret void 290end: 291 ret void 292} 293 294define void @eq_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) { 295; CHECK-LABEL: @eq_umax_contextual_commuted( 296; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Z:%.*]] 297; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]] 298; CHECK: if: 299; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]]) 300; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 301; CHECK-NEXT: call void @use(i1 [[CMP1]]) 302; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 303; CHECK-NEXT: call void @use(i1 [[CMP2]]) 304; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 305; CHECK-NEXT: call void @use(i1 [[CMP3]]) 306; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 307; CHECK-NEXT: call void @use(i1 [[CMP4]]) 308; CHECK-NEXT: call void @use(i1 false) 309; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]] 310; CHECK-NEXT: call void @use(i1 [[CMP6]]) 311; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]] 312; CHECK-NEXT: call void @use(i1 [[CMP7]]) 313; CHECK-NEXT: call void @use(i1 true) 314; CHECK-NEXT: [[CMP9:%.*]] = icmp uge i32 [[X]], [[Y]] 315; CHECK-NEXT: call void @use(i1 [[CMP9]]) 316; CHECK-NEXT: [[CMP10:%.*]] = icmp ult i32 [[X]], [[Y]] 317; CHECK-NEXT: call void @use(i1 [[CMP10]]) 318; CHECK-NEXT: ret void 319; CHECK: end: 320; CHECK-NEXT: ret void 321; 322 %cmp = icmp eq i32 %x, %z 323 br i1 %cmp, label %if, label %end 324if: 325 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x) 326 %cmp1 = icmp slt i32 %cond, %z 327 call void @use(i1 %cmp1) 328 %cmp2 = icmp sle i32 %cond, %z 329 call void @use(i1 %cmp2) 330 %cmp3 = icmp sgt i32 %cond, %z 331 call void @use(i1 %cmp3) 332 %cmp4 = icmp sge i32 %cond, %z 333 call void @use(i1 %cmp4) 334 %cmp5 = icmp ult i32 %cond, %z 335 call void @use(i1 %cmp5) 336 %cmp6 = icmp ule i32 %cond, %z 337 call void @use(i1 %cmp6) 338 %cmp7 = icmp ugt i32 %cond, %z 339 call void @use(i1 %cmp7) 340 %cmp8 = icmp uge i32 %cond, %z 341 call void @use(i1 %cmp8) 342 %cmp9 = icmp eq i32 %cond, %z 343 call void @use(i1 %cmp9) 344 %cmp10 = icmp ne i32 %cond, %z 345 call void @use(i1 %cmp10) 346 ret void 347end: 348 ret void 349} 350 351define void @ult_umax_contextual(i32 %x, i32 %y, i32 %z) { 352; CHECK-LABEL: @ult_umax_contextual( 353; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]] 354; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]] 355; CHECK: if: 356; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]]) 357; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 358; CHECK-NEXT: call void @use(i1 [[CMP1]]) 359; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 360; CHECK-NEXT: call void @use(i1 [[CMP2]]) 361; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 362; CHECK-NEXT: call void @use(i1 [[CMP3]]) 363; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 364; CHECK-NEXT: call void @use(i1 [[CMP4]]) 365; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]] 366; CHECK-NEXT: call void @use(i1 [[CMP5]]) 367; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]] 368; CHECK-NEXT: call void @use(i1 [[CMP6]]) 369; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]] 370; CHECK-NEXT: call void @use(i1 [[CMP7]]) 371; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]] 372; CHECK-NEXT: call void @use(i1 [[CMP8]]) 373; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]] 374; CHECK-NEXT: call void @use(i1 [[CMP9]]) 375; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]] 376; CHECK-NEXT: call void @use(i1 [[CMP10]]) 377; CHECK-NEXT: ret void 378; CHECK: end: 379; CHECK-NEXT: ret void 380; 381 %cmp = icmp ult i32 %x, %z 382 br i1 %cmp, label %if, label %end 383if: 384 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y) 385 %cmp1 = icmp slt i32 %cond, %z 386 call void @use(i1 %cmp1) 387 %cmp2 = icmp sle i32 %cond, %z 388 call void @use(i1 %cmp2) 389 %cmp3 = icmp sgt i32 %cond, %z 390 call void @use(i1 %cmp3) 391 %cmp4 = icmp sge i32 %cond, %z 392 call void @use(i1 %cmp4) 393 %cmp5 = icmp ult i32 %cond, %z 394 call void @use(i1 %cmp5) 395 %cmp6 = icmp ule i32 %cond, %z 396 call void @use(i1 %cmp6) 397 %cmp7 = icmp ugt i32 %cond, %z 398 call void @use(i1 %cmp7) 399 %cmp8 = icmp uge i32 %cond, %z 400 call void @use(i1 %cmp8) 401 %cmp9 = icmp eq i32 %cond, %z 402 call void @use(i1 %cmp9) 403 %cmp10 = icmp ne i32 %cond, %z 404 call void @use(i1 %cmp10) 405 ret void 406end: 407 ret void 408} 409 410define void @ult_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) { 411; CHECK-LABEL: @ult_umax_contextual_commuted( 412; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]] 413; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]] 414; CHECK: if: 415; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]]) 416; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 417; CHECK-NEXT: call void @use(i1 [[CMP1]]) 418; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 419; CHECK-NEXT: call void @use(i1 [[CMP2]]) 420; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 421; CHECK-NEXT: call void @use(i1 [[CMP3]]) 422; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 423; CHECK-NEXT: call void @use(i1 [[CMP4]]) 424; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]] 425; CHECK-NEXT: call void @use(i1 [[CMP5]]) 426; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]] 427; CHECK-NEXT: call void @use(i1 [[CMP6]]) 428; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]] 429; CHECK-NEXT: call void @use(i1 [[CMP7]]) 430; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]] 431; CHECK-NEXT: call void @use(i1 [[CMP8]]) 432; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]] 433; CHECK-NEXT: call void @use(i1 [[CMP9]]) 434; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]] 435; CHECK-NEXT: call void @use(i1 [[CMP10]]) 436; CHECK-NEXT: ret void 437; CHECK: end: 438; CHECK-NEXT: ret void 439; 440 %cmp = icmp ult i32 %x, %z 441 br i1 %cmp, label %if, label %end 442if: 443 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x) 444 %cmp1 = icmp slt i32 %cond, %z 445 call void @use(i1 %cmp1) 446 %cmp2 = icmp sle i32 %cond, %z 447 call void @use(i1 %cmp2) 448 %cmp3 = icmp sgt i32 %cond, %z 449 call void @use(i1 %cmp3) 450 %cmp4 = icmp sge i32 %cond, %z 451 call void @use(i1 %cmp4) 452 %cmp5 = icmp ult i32 %cond, %z 453 call void @use(i1 %cmp5) 454 %cmp6 = icmp ule i32 %cond, %z 455 call void @use(i1 %cmp6) 456 %cmp7 = icmp ugt i32 %cond, %z 457 call void @use(i1 %cmp7) 458 %cmp8 = icmp uge i32 %cond, %z 459 call void @use(i1 %cmp8) 460 %cmp9 = icmp eq i32 %cond, %z 461 call void @use(i1 %cmp9) 462 %cmp10 = icmp ne i32 %cond, %z 463 call void @use(i1 %cmp10) 464 ret void 465end: 466 ret void 467} 468 469define void @ule_umax_contextual(i32 %x, i32 %y, i32 %z) { 470; CHECK-LABEL: @ule_umax_contextual( 471; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]] 472; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]] 473; CHECK: if: 474; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]]) 475; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 476; CHECK-NEXT: call void @use(i1 [[CMP1]]) 477; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 478; CHECK-NEXT: call void @use(i1 [[CMP2]]) 479; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 480; CHECK-NEXT: call void @use(i1 [[CMP3]]) 481; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 482; CHECK-NEXT: call void @use(i1 [[CMP4]]) 483; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]] 484; CHECK-NEXT: call void @use(i1 [[CMP5]]) 485; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]] 486; CHECK-NEXT: call void @use(i1 [[CMP6]]) 487; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]] 488; CHECK-NEXT: call void @use(i1 [[CMP7]]) 489; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]] 490; CHECK-NEXT: call void @use(i1 [[CMP8]]) 491; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]] 492; CHECK-NEXT: call void @use(i1 [[CMP9]]) 493; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]] 494; CHECK-NEXT: call void @use(i1 [[CMP10]]) 495; CHECK-NEXT: ret void 496; CHECK: end: 497; CHECK-NEXT: ret void 498; 499 %cmp = icmp ule i32 %x, %z 500 br i1 %cmp, label %if, label %end 501if: 502 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y) 503 %cmp1 = icmp slt i32 %cond, %z 504 call void @use(i1 %cmp1) 505 %cmp2 = icmp sle i32 %cond, %z 506 call void @use(i1 %cmp2) 507 %cmp3 = icmp sgt i32 %cond, %z 508 call void @use(i1 %cmp3) 509 %cmp4 = icmp sge i32 %cond, %z 510 call void @use(i1 %cmp4) 511 %cmp5 = icmp ult i32 %cond, %z 512 call void @use(i1 %cmp5) 513 %cmp6 = icmp ule i32 %cond, %z 514 call void @use(i1 %cmp6) 515 %cmp7 = icmp ugt i32 %cond, %z 516 call void @use(i1 %cmp7) 517 %cmp8 = icmp uge i32 %cond, %z 518 call void @use(i1 %cmp8) 519 %cmp9 = icmp eq i32 %cond, %z 520 call void @use(i1 %cmp9) 521 %cmp10 = icmp ne i32 %cond, %z 522 call void @use(i1 %cmp10) 523 ret void 524end: 525 ret void 526} 527 528define void @ule_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) { 529; CHECK-LABEL: @ule_umax_contextual_commuted( 530; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]] 531; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]] 532; CHECK: if: 533; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]]) 534; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 535; CHECK-NEXT: call void @use(i1 [[CMP1]]) 536; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 537; CHECK-NEXT: call void @use(i1 [[CMP2]]) 538; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 539; CHECK-NEXT: call void @use(i1 [[CMP3]]) 540; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 541; CHECK-NEXT: call void @use(i1 [[CMP4]]) 542; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]] 543; CHECK-NEXT: call void @use(i1 [[CMP5]]) 544; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]] 545; CHECK-NEXT: call void @use(i1 [[CMP6]]) 546; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]] 547; CHECK-NEXT: call void @use(i1 [[CMP7]]) 548; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]] 549; CHECK-NEXT: call void @use(i1 [[CMP8]]) 550; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]] 551; CHECK-NEXT: call void @use(i1 [[CMP9]]) 552; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]] 553; CHECK-NEXT: call void @use(i1 [[CMP10]]) 554; CHECK-NEXT: ret void 555; CHECK: end: 556; CHECK-NEXT: ret void 557; 558 %cmp = icmp ule i32 %x, %z 559 br i1 %cmp, label %if, label %end 560if: 561 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x) 562 %cmp1 = icmp slt i32 %cond, %z 563 call void @use(i1 %cmp1) 564 %cmp2 = icmp sle i32 %cond, %z 565 call void @use(i1 %cmp2) 566 %cmp3 = icmp sgt i32 %cond, %z 567 call void @use(i1 %cmp3) 568 %cmp4 = icmp sge i32 %cond, %z 569 call void @use(i1 %cmp4) 570 %cmp5 = icmp ult i32 %cond, %z 571 call void @use(i1 %cmp5) 572 %cmp6 = icmp ule i32 %cond, %z 573 call void @use(i1 %cmp6) 574 %cmp7 = icmp ugt i32 %cond, %z 575 call void @use(i1 %cmp7) 576 %cmp8 = icmp uge i32 %cond, %z 577 call void @use(i1 %cmp8) 578 %cmp9 = icmp eq i32 %cond, %z 579 call void @use(i1 %cmp9) 580 %cmp10 = icmp ne i32 %cond, %z 581 call void @use(i1 %cmp10) 582 ret void 583end: 584 ret void 585} 586 587define void @ugt_umax_contextual(i32 %x, i32 %y, i32 %z) { 588; CHECK-LABEL: @ugt_umax_contextual( 589; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]] 590; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]] 591; CHECK: if: 592; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]]) 593; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 594; CHECK-NEXT: call void @use(i1 [[CMP1]]) 595; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 596; CHECK-NEXT: call void @use(i1 [[CMP2]]) 597; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 598; CHECK-NEXT: call void @use(i1 [[CMP3]]) 599; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 600; CHECK-NEXT: call void @use(i1 [[CMP4]]) 601; CHECK-NEXT: call void @use(i1 false) 602; CHECK-NEXT: call void @use(i1 false) 603; CHECK-NEXT: call void @use(i1 true) 604; CHECK-NEXT: call void @use(i1 true) 605; CHECK-NEXT: call void @use(i1 false) 606; CHECK-NEXT: call void @use(i1 true) 607; CHECK-NEXT: ret void 608; CHECK: end: 609; CHECK-NEXT: ret void 610; 611 %cmp = icmp ugt i32 %x, %z 612 br i1 %cmp, label %if, label %end 613if: 614 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y) 615 %cmp1 = icmp slt i32 %cond, %z 616 call void @use(i1 %cmp1) 617 %cmp2 = icmp sle i32 %cond, %z 618 call void @use(i1 %cmp2) 619 %cmp3 = icmp sgt i32 %cond, %z 620 call void @use(i1 %cmp3) 621 %cmp4 = icmp sge i32 %cond, %z 622 call void @use(i1 %cmp4) 623 %cmp5 = icmp ult i32 %cond, %z 624 call void @use(i1 %cmp5) 625 %cmp6 = icmp ule i32 %cond, %z 626 call void @use(i1 %cmp6) 627 %cmp7 = icmp ugt i32 %cond, %z 628 call void @use(i1 %cmp7) 629 %cmp8 = icmp uge i32 %cond, %z 630 call void @use(i1 %cmp8) 631 %cmp9 = icmp eq i32 %cond, %z 632 call void @use(i1 %cmp9) 633 %cmp10 = icmp ne i32 %cond, %z 634 call void @use(i1 %cmp10) 635 ret void 636end: 637 ret void 638} 639 640define void @ugt_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) { 641; CHECK-LABEL: @ugt_umax_contextual_commuted( 642; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]] 643; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]] 644; CHECK: if: 645; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]]) 646; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 647; CHECK-NEXT: call void @use(i1 [[CMP1]]) 648; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 649; CHECK-NEXT: call void @use(i1 [[CMP2]]) 650; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 651; CHECK-NEXT: call void @use(i1 [[CMP3]]) 652; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 653; CHECK-NEXT: call void @use(i1 [[CMP4]]) 654; CHECK-NEXT: call void @use(i1 false) 655; CHECK-NEXT: call void @use(i1 false) 656; CHECK-NEXT: call void @use(i1 true) 657; CHECK-NEXT: call void @use(i1 true) 658; CHECK-NEXT: call void @use(i1 false) 659; CHECK-NEXT: call void @use(i1 true) 660; CHECK-NEXT: ret void 661; CHECK: end: 662; CHECK-NEXT: ret void 663; 664 %cmp = icmp ugt i32 %x, %z 665 br i1 %cmp, label %if, label %end 666if: 667 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x) 668 %cmp1 = icmp slt i32 %cond, %z 669 call void @use(i1 %cmp1) 670 %cmp2 = icmp sle i32 %cond, %z 671 call void @use(i1 %cmp2) 672 %cmp3 = icmp sgt i32 %cond, %z 673 call void @use(i1 %cmp3) 674 %cmp4 = icmp sge i32 %cond, %z 675 call void @use(i1 %cmp4) 676 %cmp5 = icmp ult i32 %cond, %z 677 call void @use(i1 %cmp5) 678 %cmp6 = icmp ule i32 %cond, %z 679 call void @use(i1 %cmp6) 680 %cmp7 = icmp ugt i32 %cond, %z 681 call void @use(i1 %cmp7) 682 %cmp8 = icmp uge i32 %cond, %z 683 call void @use(i1 %cmp8) 684 %cmp9 = icmp eq i32 %cond, %z 685 call void @use(i1 %cmp9) 686 %cmp10 = icmp ne i32 %cond, %z 687 call void @use(i1 %cmp10) 688 ret void 689end: 690 ret void 691} 692 693define void @uge_umax_contextual(i32 %x, i32 %y, i32 %z) { 694; CHECK-LABEL: @uge_umax_contextual( 695; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]] 696; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]] 697; CHECK: if: 698; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X]], i32 [[Y:%.*]]) 699; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 700; CHECK-NEXT: call void @use(i1 [[CMP1]]) 701; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 702; CHECK-NEXT: call void @use(i1 [[CMP2]]) 703; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 704; CHECK-NEXT: call void @use(i1 [[CMP3]]) 705; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 706; CHECK-NEXT: call void @use(i1 [[CMP4]]) 707; CHECK-NEXT: call void @use(i1 false) 708; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]] 709; CHECK-NEXT: call void @use(i1 [[CMP6]]) 710; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]] 711; CHECK-NEXT: call void @use(i1 [[CMP7]]) 712; CHECK-NEXT: call void @use(i1 true) 713; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]] 714; CHECK-NEXT: call void @use(i1 [[CMP9]]) 715; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]] 716; CHECK-NEXT: call void @use(i1 [[CMP10]]) 717; CHECK-NEXT: ret void 718; CHECK: end: 719; CHECK-NEXT: ret void 720; 721 %cmp = icmp uge i32 %x, %z 722 br i1 %cmp, label %if, label %end 723if: 724 %cond = call i32 @llvm.umax.i32(i32 %x, i32 %y) 725 %cmp1 = icmp slt i32 %cond, %z 726 call void @use(i1 %cmp1) 727 %cmp2 = icmp sle i32 %cond, %z 728 call void @use(i1 %cmp2) 729 %cmp3 = icmp sgt i32 %cond, %z 730 call void @use(i1 %cmp3) 731 %cmp4 = icmp sge i32 %cond, %z 732 call void @use(i1 %cmp4) 733 %cmp5 = icmp ult i32 %cond, %z 734 call void @use(i1 %cmp5) 735 %cmp6 = icmp ule i32 %cond, %z 736 call void @use(i1 %cmp6) 737 %cmp7 = icmp ugt i32 %cond, %z 738 call void @use(i1 %cmp7) 739 %cmp8 = icmp uge i32 %cond, %z 740 call void @use(i1 %cmp8) 741 %cmp9 = icmp eq i32 %cond, %z 742 call void @use(i1 %cmp9) 743 %cmp10 = icmp ne i32 %cond, %z 744 call void @use(i1 %cmp10) 745 ret void 746end: 747 ret void 748} 749 750define void @uge_umax_contextual_commuted(i32 %x, i32 %y, i32 %z) { 751; CHECK-LABEL: @uge_umax_contextual_commuted( 752; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]] 753; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]] 754; CHECK: if: 755; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[Y:%.*]], i32 [[X]]) 756; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]] 757; CHECK-NEXT: call void @use(i1 [[CMP1]]) 758; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]] 759; CHECK-NEXT: call void @use(i1 [[CMP2]]) 760; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]] 761; CHECK-NEXT: call void @use(i1 [[CMP3]]) 762; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]] 763; CHECK-NEXT: call void @use(i1 [[CMP4]]) 764; CHECK-NEXT: call void @use(i1 false) 765; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]] 766; CHECK-NEXT: call void @use(i1 [[CMP6]]) 767; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]] 768; CHECK-NEXT: call void @use(i1 [[CMP7]]) 769; CHECK-NEXT: call void @use(i1 true) 770; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]] 771; CHECK-NEXT: call void @use(i1 [[CMP9]]) 772; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]] 773; CHECK-NEXT: call void @use(i1 [[CMP10]]) 774; CHECK-NEXT: ret void 775; CHECK: end: 776; CHECK-NEXT: ret void 777; 778 %cmp = icmp uge i32 %x, %z 779 br i1 %cmp, label %if, label %end 780if: 781 %cond = call i32 @llvm.umax.i32(i32 %y, i32 %x) 782 %cmp1 = icmp slt i32 %cond, %z 783 call void @use(i1 %cmp1) 784 %cmp2 = icmp sle i32 %cond, %z 785 call void @use(i1 %cmp2) 786 %cmp3 = icmp sgt i32 %cond, %z 787 call void @use(i1 %cmp3) 788 %cmp4 = icmp sge i32 %cond, %z 789 call void @use(i1 %cmp4) 790 %cmp5 = icmp ult i32 %cond, %z 791 call void @use(i1 %cmp5) 792 %cmp6 = icmp ule i32 %cond, %z 793 call void @use(i1 %cmp6) 794 %cmp7 = icmp ugt i32 %cond, %z 795 call void @use(i1 %cmp7) 796 %cmp8 = icmp uge i32 %cond, %z 797 call void @use(i1 %cmp8) 798 %cmp9 = icmp eq i32 %cond, %z 799 call void @use(i1 %cmp9) 800 %cmp10 = icmp ne i32 %cond, %z 801 call void @use(i1 %cmp10) 802 ret void 803end: 804 ret void 805} 806 807declare i32 @llvm.umax.i32(i32, i32) 808