808 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4; If we have a umin feeding an unsigned or equality icmp that shares an5; operand with the umin, the compare should always be folded.6; Test all 4 foldable predicates (eq,ne,uge,ult) * 4 commutation7; possibilities for each predicate. Note that folds to true/false8; (predicate is ule/ugt) or folds to an existing instruction should be9; handled by InstSimplify.10 11; umin(X, Y) == X --> X <= Y12 13define i1 @eq_umin1(i32 %x, i32 %y) {14; CHECK-LABEL: @eq_umin1(15; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]16; CHECK-NEXT: ret i1 [[CMP2]]17;18 %cmp1 = icmp ult i32 %x, %y19 %sel = select i1 %cmp1, i32 %x, i32 %y20 %cmp2 = icmp eq i32 %sel, %x21 ret i1 %cmp222}23 24; Commute min operands.25 26define i1 @eq_umin2(i32 %x, i32 %y) {27; CHECK-LABEL: @eq_umin2(28; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X:%.*]], [[Y:%.*]]29; CHECK-NEXT: ret i1 [[CMP2]]30;31 %cmp1 = icmp ult i32 %y, %x32 %sel = select i1 %cmp1, i32 %y, i32 %x33 %cmp2 = icmp eq i32 %sel, %x34 ret i1 %cmp235}36 37; Disguise the icmp predicate by commuting the min op to the RHS.38 39define i1 @eq_umin3(i32 %a, i32 %y) {40; CHECK-LABEL: @eq_umin3(41; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 342; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[Y:%.*]]43; CHECK-NEXT: ret i1 [[CMP2]]44;45 %x = add i32 %a, 3 ; thwart complexity-based canonicalization46 %cmp1 = icmp ult i32 %x, %y47 %sel = select i1 %cmp1, i32 %x, i32 %y48 %cmp2 = icmp eq i32 %x, %sel49 ret i1 %cmp250}51 52; Commute min operands.53 54define i1 @eq_umin4(i32 %a, i32 %y) {55; CHECK-LABEL: @eq_umin4(56; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 357; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], [[Y:%.*]]58; CHECK-NEXT: ret i1 [[CMP2]]59;60 %x = add i32 %a, 3 ; thwart complexity-based canonicalization61 %cmp1 = icmp ult i32 %y, %x62 %sel = select i1 %cmp1, i32 %y, i32 %x63 %cmp2 = icmp eq i32 %x, %sel64 ret i1 %cmp265}66 67; umin(X, Y) >= X --> Y >= X68 69define i1 @uge_umin1(i32 %x, i32 %y) {70; CHECK-LABEL: @uge_umin1(71; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[Y:%.*]], [[X:%.*]]72; CHECK-NEXT: ret i1 [[CMP2]]73;74 %cmp1 = icmp ult i32 %x, %y75 %sel = select i1 %cmp1, i32 %x, i32 %y76 %cmp2 = icmp uge i32 %sel, %x77 ret i1 %cmp278}79 80; Commute min operands.81 82define i1 @uge_umin2(i32 %x, i32 %y) {83; CHECK-LABEL: @uge_umin2(84; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[Y:%.*]], [[X:%.*]]85; CHECK-NEXT: ret i1 [[CMP2]]86;87 %cmp1 = icmp ult i32 %y, %x88 %sel = select i1 %cmp1, i32 %y, i32 %x89 %cmp2 = icmp uge i32 %sel, %x90 ret i1 %cmp291}92 93; Disguise the icmp predicate by commuting the min op to the RHS.94 95define i1 @uge_umin3(i32 %a, i32 %y) {96; CHECK-LABEL: @uge_umin3(97; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 398; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[Y:%.*]], [[X]]99; CHECK-NEXT: ret i1 [[CMP2]]100;101 %x = add i32 %a, 3 ; thwart complexity-based canonicalization102 %cmp1 = icmp ult i32 %x, %y103 %sel = select i1 %cmp1, i32 %x, i32 %y104 %cmp2 = icmp ule i32 %x, %sel105 ret i1 %cmp2106}107 108; Commute min operands.109 110define i1 @uge_umin4(i32 %a, i32 %y) {111; CHECK-LABEL: @uge_umin4(112; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3113; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i32 [[Y:%.*]], [[X]]114; CHECK-NEXT: ret i1 [[CMP2]]115;116 %x = add i32 %a, 3 ; thwart complexity-based canonicalization117 %cmp1 = icmp ult i32 %y, %x118 %sel = select i1 %cmp1, i32 %y, i32 %x119 %cmp2 = icmp ule i32 %x, %sel120 ret i1 %cmp2121}122 123; umin(X, Y) != X --> X > Y124 125define i1 @ne_umin1(i32 %x, i32 %y) {126; CHECK-LABEL: @ne_umin1(127; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]128; CHECK-NEXT: ret i1 [[CMP2]]129;130 %cmp1 = icmp ult i32 %x, %y131 %sel = select i1 %cmp1, i32 %x, i32 %y132 %cmp2 = icmp ne i32 %sel, %x133 ret i1 %cmp2134}135 136; Commute min operands.137 138define i1 @ne_umin2(i32 %x, i32 %y) {139; CHECK-LABEL: @ne_umin2(140; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]141; CHECK-NEXT: ret i1 [[CMP2]]142;143 %cmp1 = icmp ult i32 %y, %x144 %sel = select i1 %cmp1, i32 %y, i32 %x145 %cmp2 = icmp ne i32 %sel, %x146 ret i1 %cmp2147}148 149; Disguise the icmp predicate by commuting the min op to the RHS.150 151define i1 @ne_umin3(i32 %a, i32 %y) {152; CHECK-LABEL: @ne_umin3(153; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3154; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], [[Y:%.*]]155; CHECK-NEXT: ret i1 [[CMP2]]156;157 %x = add i32 %a, 3 ; thwart complexity-based canonicalization158 %cmp1 = icmp ult i32 %x, %y159 %sel = select i1 %cmp1, i32 %x, i32 %y160 %cmp2 = icmp ne i32 %x, %sel161 ret i1 %cmp2162}163 164; Commute min operands.165 166define i1 @ne_umin4(i32 %a, i32 %y) {167; CHECK-LABEL: @ne_umin4(168; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3169; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], [[Y:%.*]]170; CHECK-NEXT: ret i1 [[CMP2]]171;172 %x = add i32 %a, 3 ; thwart complexity-based canonicalization173 %cmp1 = icmp ult i32 %y, %x174 %sel = select i1 %cmp1, i32 %y, i32 %x175 %cmp2 = icmp ne i32 %x, %sel176 ret i1 %cmp2177}178 179; umin(X, Y) < X --> Y < X180 181define i1 @ult_umin1(i32 %x, i32 %y) {182; CHECK-LABEL: @ult_umin1(183; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]184; CHECK-NEXT: ret i1 [[CMP2]]185;186 %cmp1 = icmp ult i32 %x, %y187 %sel = select i1 %cmp1, i32 %x, i32 %y188 %cmp2 = icmp ult i32 %sel, %x189 ret i1 %cmp2190}191 192; Commute min operands.193 194define i1 @ult_umin2(i32 %x, i32 %y) {195; CHECK-LABEL: @ult_umin2(196; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X:%.*]]197; CHECK-NEXT: ret i1 [[CMP2]]198;199 %cmp1 = icmp ult i32 %y, %x200 %sel = select i1 %cmp1, i32 %y, i32 %x201 %cmp2 = icmp ult i32 %sel, %x202 ret i1 %cmp2203}204 205; Disguise the icmp predicate by commuting the min op to the RHS.206 207define i1 @ult_umin3(i32 %a, i32 %y) {208; CHECK-LABEL: @ult_umin3(209; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3210; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X]]211; CHECK-NEXT: ret i1 [[CMP2]]212;213 %x = add i32 %a, 3 ; thwart complexity-based canonicalization214 %cmp1 = icmp ult i32 %x, %y215 %sel = select i1 %cmp1, i32 %x, i32 %y216 %cmp2 = icmp ugt i32 %x, %sel217 ret i1 %cmp2218}219 220; Commute min operands.221 222define i1 @ult_umin4(i32 %a, i32 %y) {223; CHECK-LABEL: @ult_umin4(224; CHECK-NEXT: [[X:%.*]] = add i32 [[A:%.*]], 3225; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[Y:%.*]], [[X]]226; CHECK-NEXT: ret i1 [[CMP2]]227;228 %x = add i32 %a, 3 ; thwart complexity-based canonicalization229 %cmp1 = icmp ult i32 %y, %x230 %sel = select i1 %cmp1, i32 %y, i32 %x231 %cmp2 = icmp ugt i32 %x, %sel232 ret i1 %cmp2233}234 235declare void @use(i1 %c)236 237define void @eq_umin_contextual(i32 %x, i32 %y, i32 %z) {238; CHECK-LABEL: @eq_umin_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.umin.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: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]252; CHECK-NEXT: call void @use(i1 [[CMP5]])253; CHECK-NEXT: call void @use(i1 true)254; CHECK-NEXT: call void @use(i1 false)255; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]256; CHECK-NEXT: call void @use(i1 [[CMP8]])257; CHECK-NEXT: [[CMP9:%.*]] = icmp ule i32 [[X]], [[Y]]258; CHECK-NEXT: call void @use(i1 [[CMP9]])259; CHECK-NEXT: [[CMP10:%.*]] = icmp ugt i32 [[X]], [[Y]]260; CHECK-NEXT: call void @use(i1 [[CMP10]])261; CHECK-NEXT: ret void262; CHECK: end:263; CHECK-NEXT: ret void264;265 %cmp = icmp eq i32 %x, %z266 br i1 %cmp, label %if, label %end267if:268 %cond = call i32 @llvm.umin.i32(i32 %x, i32 %y)269 %cmp1 = icmp slt i32 %cond, %z270 call void @use(i1 %cmp1)271 %cmp2 = icmp sle i32 %cond, %z272 call void @use(i1 %cmp2)273 %cmp3 = icmp sgt i32 %cond, %z274 call void @use(i1 %cmp3)275 %cmp4 = icmp sge i32 %cond, %z276 call void @use(i1 %cmp4)277 %cmp5 = icmp ult i32 %cond, %z278 call void @use(i1 %cmp5)279 %cmp6 = icmp ule i32 %cond, %z280 call void @use(i1 %cmp6)281 %cmp7 = icmp ugt i32 %cond, %z282 call void @use(i1 %cmp7)283 %cmp8 = icmp uge i32 %cond, %z284 call void @use(i1 %cmp8)285 %cmp9 = icmp eq i32 %cond, %z286 call void @use(i1 %cmp9)287 %cmp10 = icmp ne i32 %cond, %z288 call void @use(i1 %cmp10)289 ret void290end:291 ret void292}293 294define void @eq_umin_contextual_commuted(i32 %x, i32 %y, i32 %z) {295; CHECK-LABEL: @eq_umin_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.umin.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: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]309; CHECK-NEXT: call void @use(i1 [[CMP5]])310; CHECK-NEXT: call void @use(i1 true)311; CHECK-NEXT: call void @use(i1 false)312; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]313; CHECK-NEXT: call void @use(i1 [[CMP8]])314; CHECK-NEXT: [[CMP9:%.*]] = icmp ule i32 [[X]], [[Y]]315; CHECK-NEXT: call void @use(i1 [[CMP9]])316; CHECK-NEXT: [[CMP10:%.*]] = icmp ugt i32 [[X]], [[Y]]317; CHECK-NEXT: call void @use(i1 [[CMP10]])318; CHECK-NEXT: ret void319; CHECK: end:320; CHECK-NEXT: ret void321;322 %cmp = icmp eq i32 %x, %z323 br i1 %cmp, label %if, label %end324if:325 %cond = call i32 @llvm.umin.i32(i32 %y, i32 %x)326 %cmp1 = icmp slt i32 %cond, %z327 call void @use(i1 %cmp1)328 %cmp2 = icmp sle i32 %cond, %z329 call void @use(i1 %cmp2)330 %cmp3 = icmp sgt i32 %cond, %z331 call void @use(i1 %cmp3)332 %cmp4 = icmp sge i32 %cond, %z333 call void @use(i1 %cmp4)334 %cmp5 = icmp ult i32 %cond, %z335 call void @use(i1 %cmp5)336 %cmp6 = icmp ule i32 %cond, %z337 call void @use(i1 %cmp6)338 %cmp7 = icmp ugt i32 %cond, %z339 call void @use(i1 %cmp7)340 %cmp8 = icmp uge i32 %cond, %z341 call void @use(i1 %cmp8)342 %cmp9 = icmp eq i32 %cond, %z343 call void @use(i1 %cmp9)344 %cmp10 = icmp ne i32 %cond, %z345 call void @use(i1 %cmp10)346 ret void347end:348 ret void349}350 351define void @ult_umin_contextual(i32 %x, i32 %y, i32 %z) {352; CHECK-LABEL: @ult_umin_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.umin.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: call void @use(i1 true)366; CHECK-NEXT: call void @use(i1 true)367; CHECK-NEXT: call void @use(i1 false)368; CHECK-NEXT: call void @use(i1 false)369; CHECK-NEXT: call void @use(i1 false)370; CHECK-NEXT: call void @use(i1 true)371; CHECK-NEXT: ret void372; CHECK: end:373; CHECK-NEXT: ret void374;375 %cmp = icmp ult i32 %x, %z376 br i1 %cmp, label %if, label %end377if:378 %cond = call i32 @llvm.umin.i32(i32 %x, i32 %y)379 %cmp1 = icmp slt i32 %cond, %z380 call void @use(i1 %cmp1)381 %cmp2 = icmp sle i32 %cond, %z382 call void @use(i1 %cmp2)383 %cmp3 = icmp sgt i32 %cond, %z384 call void @use(i1 %cmp3)385 %cmp4 = icmp sge i32 %cond, %z386 call void @use(i1 %cmp4)387 %cmp5 = icmp ult i32 %cond, %z388 call void @use(i1 %cmp5)389 %cmp6 = icmp ule i32 %cond, %z390 call void @use(i1 %cmp6)391 %cmp7 = icmp ugt i32 %cond, %z392 call void @use(i1 %cmp7)393 %cmp8 = icmp uge i32 %cond, %z394 call void @use(i1 %cmp8)395 %cmp9 = icmp eq i32 %cond, %z396 call void @use(i1 %cmp9)397 %cmp10 = icmp ne i32 %cond, %z398 call void @use(i1 %cmp10)399 ret void400end:401 ret void402}403 404define void @ult_umin_contextual_commuted(i32 %x, i32 %y, i32 %z) {405; CHECK-LABEL: @ult_umin_contextual_commuted(406; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]407; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]408; CHECK: if:409; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[Y:%.*]], i32 [[X]])410; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]411; CHECK-NEXT: call void @use(i1 [[CMP1]])412; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]413; CHECK-NEXT: call void @use(i1 [[CMP2]])414; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]415; CHECK-NEXT: call void @use(i1 [[CMP3]])416; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]417; CHECK-NEXT: call void @use(i1 [[CMP4]])418; CHECK-NEXT: call void @use(i1 true)419; CHECK-NEXT: call void @use(i1 true)420; CHECK-NEXT: call void @use(i1 false)421; CHECK-NEXT: call void @use(i1 false)422; CHECK-NEXT: call void @use(i1 false)423; CHECK-NEXT: call void @use(i1 true)424; CHECK-NEXT: ret void425; CHECK: end:426; CHECK-NEXT: ret void427;428 %cmp = icmp ult i32 %x, %z429 br i1 %cmp, label %if, label %end430if:431 %cond = call i32 @llvm.umin.i32(i32 %y, i32 %x)432 %cmp1 = icmp slt i32 %cond, %z433 call void @use(i1 %cmp1)434 %cmp2 = icmp sle i32 %cond, %z435 call void @use(i1 %cmp2)436 %cmp3 = icmp sgt i32 %cond, %z437 call void @use(i1 %cmp3)438 %cmp4 = icmp sge i32 %cond, %z439 call void @use(i1 %cmp4)440 %cmp5 = icmp ult i32 %cond, %z441 call void @use(i1 %cmp5)442 %cmp6 = icmp ule i32 %cond, %z443 call void @use(i1 %cmp6)444 %cmp7 = icmp ugt i32 %cond, %z445 call void @use(i1 %cmp7)446 %cmp8 = icmp uge i32 %cond, %z447 call void @use(i1 %cmp8)448 %cmp9 = icmp eq i32 %cond, %z449 call void @use(i1 %cmp9)450 %cmp10 = icmp ne i32 %cond, %z451 call void @use(i1 %cmp10)452 ret void453end:454 ret void455}456 457define void @ule_umin_contextual(i32 %x, i32 %y, i32 %z) {458; CHECK-LABEL: @ule_umin_contextual(459; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]460; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]461; CHECK: if:462; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y:%.*]])463; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]464; CHECK-NEXT: call void @use(i1 [[CMP1]])465; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]466; CHECK-NEXT: call void @use(i1 [[CMP2]])467; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]468; CHECK-NEXT: call void @use(i1 [[CMP3]])469; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]470; CHECK-NEXT: call void @use(i1 [[CMP4]])471; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]472; CHECK-NEXT: call void @use(i1 [[CMP5]])473; CHECK-NEXT: call void @use(i1 true)474; CHECK-NEXT: call void @use(i1 false)475; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]476; CHECK-NEXT: call void @use(i1 [[CMP8]])477; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]478; CHECK-NEXT: call void @use(i1 [[CMP9]])479; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]480; CHECK-NEXT: call void @use(i1 [[CMP10]])481; CHECK-NEXT: ret void482; CHECK: end:483; CHECK-NEXT: ret void484;485 %cmp = icmp ule i32 %x, %z486 br i1 %cmp, label %if, label %end487if:488 %cond = call i32 @llvm.umin.i32(i32 %x, i32 %y)489 %cmp1 = icmp slt i32 %cond, %z490 call void @use(i1 %cmp1)491 %cmp2 = icmp sle i32 %cond, %z492 call void @use(i1 %cmp2)493 %cmp3 = icmp sgt i32 %cond, %z494 call void @use(i1 %cmp3)495 %cmp4 = icmp sge i32 %cond, %z496 call void @use(i1 %cmp4)497 %cmp5 = icmp ult i32 %cond, %z498 call void @use(i1 %cmp5)499 %cmp6 = icmp ule i32 %cond, %z500 call void @use(i1 %cmp6)501 %cmp7 = icmp ugt i32 %cond, %z502 call void @use(i1 %cmp7)503 %cmp8 = icmp uge i32 %cond, %z504 call void @use(i1 %cmp8)505 %cmp9 = icmp eq i32 %cond, %z506 call void @use(i1 %cmp9)507 %cmp10 = icmp ne i32 %cond, %z508 call void @use(i1 %cmp10)509 ret void510end:511 ret void512}513 514define void @ule_umin_contextual_commuted(i32 %x, i32 %y, i32 %z) {515; CHECK-LABEL: @ule_umin_contextual_commuted(516; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]517; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]518; CHECK: if:519; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[Y:%.*]], i32 [[X]])520; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]521; CHECK-NEXT: call void @use(i1 [[CMP1]])522; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]523; CHECK-NEXT: call void @use(i1 [[CMP2]])524; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]525; CHECK-NEXT: call void @use(i1 [[CMP3]])526; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]527; CHECK-NEXT: call void @use(i1 [[CMP4]])528; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]529; CHECK-NEXT: call void @use(i1 [[CMP5]])530; CHECK-NEXT: call void @use(i1 true)531; CHECK-NEXT: call void @use(i1 false)532; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]533; CHECK-NEXT: call void @use(i1 [[CMP8]])534; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]535; CHECK-NEXT: call void @use(i1 [[CMP9]])536; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]537; CHECK-NEXT: call void @use(i1 [[CMP10]])538; CHECK-NEXT: ret void539; CHECK: end:540; CHECK-NEXT: ret void541;542 %cmp = icmp ule i32 %x, %z543 br i1 %cmp, label %if, label %end544if:545 %cond = call i32 @llvm.umin.i32(i32 %y, i32 %x)546 %cmp1 = icmp slt i32 %cond, %z547 call void @use(i1 %cmp1)548 %cmp2 = icmp sle i32 %cond, %z549 call void @use(i1 %cmp2)550 %cmp3 = icmp sgt i32 %cond, %z551 call void @use(i1 %cmp3)552 %cmp4 = icmp sge i32 %cond, %z553 call void @use(i1 %cmp4)554 %cmp5 = icmp ult i32 %cond, %z555 call void @use(i1 %cmp5)556 %cmp6 = icmp ule i32 %cond, %z557 call void @use(i1 %cmp6)558 %cmp7 = icmp ugt i32 %cond, %z559 call void @use(i1 %cmp7)560 %cmp8 = icmp uge i32 %cond, %z561 call void @use(i1 %cmp8)562 %cmp9 = icmp eq i32 %cond, %z563 call void @use(i1 %cmp9)564 %cmp10 = icmp ne i32 %cond, %z565 call void @use(i1 %cmp10)566 ret void567end:568 ret void569}570 571define void @ugt_umin_contextual(i32 %x, i32 %y, i32 %z) {572; CHECK-LABEL: @ugt_umin_contextual(573; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]574; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]575; CHECK: if:576; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y:%.*]])577; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]578; CHECK-NEXT: call void @use(i1 [[CMP1]])579; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]580; CHECK-NEXT: call void @use(i1 [[CMP2]])581; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]582; CHECK-NEXT: call void @use(i1 [[CMP3]])583; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]584; CHECK-NEXT: call void @use(i1 [[CMP4]])585; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]586; CHECK-NEXT: call void @use(i1 [[CMP5]])587; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]588; CHECK-NEXT: call void @use(i1 [[CMP6]])589; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]590; CHECK-NEXT: call void @use(i1 [[CMP7]])591; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]592; CHECK-NEXT: call void @use(i1 [[CMP8]])593; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]594; CHECK-NEXT: call void @use(i1 [[CMP9]])595; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]596; CHECK-NEXT: call void @use(i1 [[CMP10]])597; CHECK-NEXT: ret void598; CHECK: end:599; CHECK-NEXT: ret void600;601 %cmp = icmp ugt i32 %x, %z602 br i1 %cmp, label %if, label %end603if:604 %cond = call i32 @llvm.umin.i32(i32 %x, i32 %y)605 %cmp1 = icmp slt i32 %cond, %z606 call void @use(i1 %cmp1)607 %cmp2 = icmp sle i32 %cond, %z608 call void @use(i1 %cmp2)609 %cmp3 = icmp sgt i32 %cond, %z610 call void @use(i1 %cmp3)611 %cmp4 = icmp sge i32 %cond, %z612 call void @use(i1 %cmp4)613 %cmp5 = icmp ult i32 %cond, %z614 call void @use(i1 %cmp5)615 %cmp6 = icmp ule i32 %cond, %z616 call void @use(i1 %cmp6)617 %cmp7 = icmp ugt i32 %cond, %z618 call void @use(i1 %cmp7)619 %cmp8 = icmp uge i32 %cond, %z620 call void @use(i1 %cmp8)621 %cmp9 = icmp eq i32 %cond, %z622 call void @use(i1 %cmp9)623 %cmp10 = icmp ne i32 %cond, %z624 call void @use(i1 %cmp10)625 ret void626end:627 ret void628}629 630define void @ugt_umin_contextual_commuted(i32 %x, i32 %y, i32 %z) {631; CHECK-LABEL: @ugt_umin_contextual_commuted(632; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Z:%.*]]633; CHECK-NEXT: br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]634; CHECK: if:635; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[Y:%.*]], i32 [[X]])636; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]637; CHECK-NEXT: call void @use(i1 [[CMP1]])638; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]639; CHECK-NEXT: call void @use(i1 [[CMP2]])640; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]641; CHECK-NEXT: call void @use(i1 [[CMP3]])642; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]643; CHECK-NEXT: call void @use(i1 [[CMP4]])644; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]645; CHECK-NEXT: call void @use(i1 [[CMP5]])646; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[Y]], [[Z]]647; CHECK-NEXT: call void @use(i1 [[CMP6]])648; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[Y]], [[Z]]649; CHECK-NEXT: call void @use(i1 [[CMP7]])650; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]651; CHECK-NEXT: call void @use(i1 [[CMP8]])652; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[Y]], [[Z]]653; CHECK-NEXT: call void @use(i1 [[CMP9]])654; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[Y]], [[Z]]655; CHECK-NEXT: call void @use(i1 [[CMP10]])656; CHECK-NEXT: ret void657; CHECK: end:658; CHECK-NEXT: ret void659;660 %cmp = icmp ugt i32 %x, %z661 br i1 %cmp, label %if, label %end662if:663 %cond = call i32 @llvm.umin.i32(i32 %y, i32 %x)664 %cmp1 = icmp slt i32 %cond, %z665 call void @use(i1 %cmp1)666 %cmp2 = icmp sle i32 %cond, %z667 call void @use(i1 %cmp2)668 %cmp3 = icmp sgt i32 %cond, %z669 call void @use(i1 %cmp3)670 %cmp4 = icmp sge i32 %cond, %z671 call void @use(i1 %cmp4)672 %cmp5 = icmp ult i32 %cond, %z673 call void @use(i1 %cmp5)674 %cmp6 = icmp ule i32 %cond, %z675 call void @use(i1 %cmp6)676 %cmp7 = icmp ugt i32 %cond, %z677 call void @use(i1 %cmp7)678 %cmp8 = icmp uge i32 %cond, %z679 call void @use(i1 %cmp8)680 %cmp9 = icmp eq i32 %cond, %z681 call void @use(i1 %cmp9)682 %cmp10 = icmp ne i32 %cond, %z683 call void @use(i1 %cmp10)684 ret void685end:686 ret void687}688 689define void @uge_umin_contextual(i32 %x, i32 %y, i32 %z) {690; CHECK-LABEL: @uge_umin_contextual(691; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]692; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]693; CHECK: if:694; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[Y:%.*]])695; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]696; CHECK-NEXT: call void @use(i1 [[CMP1]])697; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]698; CHECK-NEXT: call void @use(i1 [[CMP2]])699; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]700; CHECK-NEXT: call void @use(i1 [[CMP3]])701; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]702; CHECK-NEXT: call void @use(i1 [[CMP4]])703; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]704; CHECK-NEXT: call void @use(i1 [[CMP5]])705; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]706; CHECK-NEXT: call void @use(i1 [[CMP6]])707; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]708; CHECK-NEXT: call void @use(i1 [[CMP7]])709; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]710; CHECK-NEXT: call void @use(i1 [[CMP8]])711; CHECK-NEXT: [[CMP9:%.*]] = icmp eq i32 [[COND]], [[Z]]712; CHECK-NEXT: call void @use(i1 [[CMP9]])713; CHECK-NEXT: [[CMP10:%.*]] = icmp ne i32 [[COND]], [[Z]]714; CHECK-NEXT: call void @use(i1 [[CMP10]])715; CHECK-NEXT: ret void716; CHECK: end:717; CHECK-NEXT: ret void718;719 %cmp = icmp uge i32 %x, %z720 br i1 %cmp, label %if, label %end721if:722 %cond = call i32 @llvm.umin.i32(i32 %x, i32 %y)723 %cmp1 = icmp slt i32 %cond, %z724 call void @use(i1 %cmp1)725 %cmp2 = icmp sle i32 %cond, %z726 call void @use(i1 %cmp2)727 %cmp3 = icmp sgt i32 %cond, %z728 call void @use(i1 %cmp3)729 %cmp4 = icmp sge i32 %cond, %z730 call void @use(i1 %cmp4)731 %cmp5 = icmp ult i32 %cond, %z732 call void @use(i1 %cmp5)733 %cmp6 = icmp ule i32 %cond, %z734 call void @use(i1 %cmp6)735 %cmp7 = icmp ugt i32 %cond, %z736 call void @use(i1 %cmp7)737 %cmp8 = icmp uge i32 %cond, %z738 call void @use(i1 %cmp8)739 %cmp9 = icmp eq i32 %cond, %z740 call void @use(i1 %cmp9)741 %cmp10 = icmp ne i32 %cond, %z742 call void @use(i1 %cmp10)743 ret void744end:745 ret void746}747 748define void @uge_umin_contextual_commuted(i32 %x, i32 %y, i32 %z) {749; CHECK-LABEL: @uge_umin_contextual_commuted(750; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp ult i32 [[X:%.*]], [[Z:%.*]]751; CHECK-NEXT: br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]752; CHECK: if:753; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[Y:%.*]], i32 [[X]])754; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[COND]], [[Z]]755; CHECK-NEXT: call void @use(i1 [[CMP1]])756; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]757; CHECK-NEXT: call void @use(i1 [[CMP2]])758; CHECK-NEXT: [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]759; CHECK-NEXT: call void @use(i1 [[CMP3]])760; CHECK-NEXT: [[CMP4:%.*]] = icmp sge i32 [[COND]], [[Z]]761; CHECK-NEXT: call void @use(i1 [[CMP4]])762; CHECK-NEXT: [[CMP5:%.*]] = icmp ult i32 [[Y]], [[Z]]763; CHECK-NEXT: call void @use(i1 [[CMP5]])764; CHECK-NEXT: [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]765; CHECK-NEXT: call void @use(i1 [[CMP6]])766; CHECK-NEXT: [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]767; CHECK-NEXT: call void @use(i1 [[CMP7]])768; CHECK-NEXT: [[CMP8:%.*]] = icmp uge i32 [[Y]], [[Z]]769; CHECK-NEXT: call void @use(i1 [[CMP8]])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 void775; CHECK: end:776; CHECK-NEXT: ret void777;778 %cmp = icmp uge i32 %x, %z779 br i1 %cmp, label %if, label %end780if:781 %cond = call i32 @llvm.umin.i32(i32 %y, i32 %x)782 %cmp1 = icmp slt i32 %cond, %z783 call void @use(i1 %cmp1)784 %cmp2 = icmp sle i32 %cond, %z785 call void @use(i1 %cmp2)786 %cmp3 = icmp sgt i32 %cond, %z787 call void @use(i1 %cmp3)788 %cmp4 = icmp sge i32 %cond, %z789 call void @use(i1 %cmp4)790 %cmp5 = icmp ult i32 %cond, %z791 call void @use(i1 %cmp5)792 %cmp6 = icmp ule i32 %cond, %z793 call void @use(i1 %cmp6)794 %cmp7 = icmp ugt i32 %cond, %z795 call void @use(i1 %cmp7)796 %cmp8 = icmp uge i32 %cond, %z797 call void @use(i1 %cmp8)798 %cmp9 = icmp eq i32 %cond, %z799 call void @use(i1 %cmp9)800 %cmp10 = icmp ne i32 %cond, %z801 call void @use(i1 %cmp10)802 ret void803end:804 ret void805}806 807declare i32 @llvm.umin.i32(i32, i32)808