brintos

brintos / llvm-project-archived public Read only

0
0
Text · 27.8 KiB · 4c9cbed Raw
849 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 an smax feeding a signed or equality icmp that shares an5; operand with the smax, the compare should always be folded.6; Test all 4 foldable predicates (eq,ne,sgt,sle) * 4 commutation7; possibilities for each predicate. Note that folds to true/false8; (predicate = sge/slt) or folds to an existing instruction should be9; handled by InstSimplify.10 11; smax(X, Y) == X --> X >= Y12 13define i1 @eq_smax1(i32 %x, i32 %y) {14; CHECK-LABEL: @eq_smax1(15; CHECK-NEXT:    [[CMP2:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]16; CHECK-NEXT:    ret i1 [[CMP2]]17;18  %cmp1 = icmp sgt i32 %x, %y19  %sel = select i1 %cmp1, i32 %x, i32 %y20  %cmp2 = icmp eq i32 %sel, %x21  ret i1 %cmp222}23 24; Commute max operands.25 26define i1 @eq_smax2(i32 %x, i32 %y) {27; CHECK-LABEL: @eq_smax2(28; CHECK-NEXT:    [[CMP2:%.*]] = icmp sge i32 [[X:%.*]], [[Y:%.*]]29; CHECK-NEXT:    ret i1 [[CMP2]]30;31  %cmp1 = icmp sgt 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 max op to the RHS.38 39define i1 @eq_smax3(i32 %a, i32 %y) {40; CHECK-LABEL: @eq_smax3(41; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 342; CHECK-NEXT:    [[CMP2:%.*]] = icmp sge i32 [[X]], [[Y:%.*]]43; CHECK-NEXT:    ret i1 [[CMP2]]44;45  %x = add i32 %a, 3 ; thwart complexity-based canonicalization46  %cmp1 = icmp sgt i32 %x, %y47  %sel = select i1 %cmp1, i32 %x, i32 %y48  %cmp2 = icmp eq i32 %x, %sel49  ret i1 %cmp250}51 52; Commute max operands.53 54define i1 @eq_smax4(i32 %a, i32 %y) {55; CHECK-LABEL: @eq_smax4(56; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 357; CHECK-NEXT:    [[CMP2:%.*]] = icmp sge i32 [[X]], [[Y:%.*]]58; CHECK-NEXT:    ret i1 [[CMP2]]59;60  %x = add i32 %a, 3 ; thwart complexity-based canonicalization61  %cmp1 = icmp sgt i32 %y, %x62  %sel = select i1 %cmp1, i32 %y, i32 %x63  %cmp2 = icmp eq i32 %x, %sel64  ret i1 %cmp265}66 67; smax(X, Y) <= X --> Y <= X68 69define i1 @sle_smax1(i32 %x, i32 %y) {70; CHECK-LABEL: @sle_smax1(71; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y:%.*]], [[X:%.*]]72; CHECK-NEXT:    ret i1 [[CMP2]]73;74  %cmp1 = icmp sgt i32 %x, %y75  %sel = select i1 %cmp1, i32 %x, i32 %y76  %cmp2 = icmp sle i32 %sel, %x77  ret i1 %cmp278}79 80; Commute max operands.81 82define i1 @sle_smax2(i32 %x, i32 %y) {83; CHECK-LABEL: @sle_smax2(84; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y:%.*]], [[X:%.*]]85; CHECK-NEXT:    ret i1 [[CMP2]]86;87  %cmp1 = icmp sgt i32 %y, %x88  %sel = select i1 %cmp1, i32 %y, i32 %x89  %cmp2 = icmp sle i32 %sel, %x90  ret i1 %cmp291}92 93; Disguise the icmp predicate by commuting the max op to the RHS.94 95define i1 @sle_smax3(i32 %a, i32 %y) {96; CHECK-LABEL: @sle_smax3(97; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 398; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y:%.*]], [[X]]99; CHECK-NEXT:    ret i1 [[CMP2]]100;101  %x = add i32 %a, 3 ; thwart complexity-based canonicalization102  %cmp1 = icmp sgt i32 %x, %y103  %sel = select i1 %cmp1, i32 %x, i32 %y104  %cmp2 = icmp sge i32 %x, %sel105  ret i1 %cmp2106}107 108; Commute max operands.109 110define i1 @sle_smax4(i32 %a, i32 %y) {111; CHECK-LABEL: @sle_smax4(112; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 3113; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y:%.*]], [[X]]114; CHECK-NEXT:    ret i1 [[CMP2]]115;116  %x = add i32 %a, 3 ; thwart complexity-based canonicalization117  %cmp1 = icmp sgt i32 %y, %x118  %sel = select i1 %cmp1, i32 %y, i32 %x119  %cmp2 = icmp sge i32 %x, %sel120  ret i1 %cmp2121}122 123; smax(X, Y) != X --> X < Y124 125define i1 @ne_smax1(i32 %x, i32 %y) {126; CHECK-LABEL: @ne_smax1(127; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]128; CHECK-NEXT:    ret i1 [[CMP2]]129;130  %cmp1 = icmp sgt i32 %x, %y131  %sel = select i1 %cmp1, i32 %x, i32 %y132  %cmp2 = icmp ne i32 %sel, %x133  ret i1 %cmp2134}135 136; Commute max operands.137 138define i1 @ne_smax2(i32 %x, i32 %y) {139; CHECK-LABEL: @ne_smax2(140; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]141; CHECK-NEXT:    ret i1 [[CMP2]]142;143  %cmp1 = icmp sgt 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 max op to the RHS.150 151define i1 @ne_smax3(i32 %a, i32 %y) {152; CHECK-LABEL: @ne_smax3(153; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 3154; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], [[Y:%.*]]155; CHECK-NEXT:    ret i1 [[CMP2]]156;157  %x = add i32 %a, 3 ; thwart complexity-based canonicalization158  %cmp1 = icmp sgt i32 %x, %y159  %sel = select i1 %cmp1, i32 %x, i32 %y160  %cmp2 = icmp ne i32 %x, %sel161  ret i1 %cmp2162}163 164; Commute max operands.165 166define i1 @ne_smax4(i32 %a, i32 %y) {167; CHECK-LABEL: @ne_smax4(168; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 3169; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], [[Y:%.*]]170; CHECK-NEXT:    ret i1 [[CMP2]]171;172  %x = add i32 %a, 3 ; thwart complexity-based canonicalization173  %cmp1 = icmp sgt i32 %y, %x174  %sel = select i1 %cmp1, i32 %y, i32 %x175  %cmp2 = icmp ne i32 %x, %sel176  ret i1 %cmp2177}178 179; smax(X, Y) > X --> Y > X180 181define i1 @sgt_smax1(i32 %x, i32 %y) {182; CHECK-LABEL: @sgt_smax1(183; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X:%.*]]184; CHECK-NEXT:    ret i1 [[CMP2]]185;186  %cmp1 = icmp sgt i32 %x, %y187  %sel = select i1 %cmp1, i32 %x, i32 %y188  %cmp2 = icmp sgt i32 %sel, %x189  ret i1 %cmp2190}191 192; Commute max operands.193 194define i1 @sgt_smax2(i32 %x, i32 %y) {195; CHECK-LABEL: @sgt_smax2(196; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X:%.*]]197; CHECK-NEXT:    ret i1 [[CMP2]]198;199  %cmp1 = icmp sgt i32 %y, %x200  %sel = select i1 %cmp1, i32 %y, i32 %x201  %cmp2 = icmp sgt i32 %sel, %x202  ret i1 %cmp2203}204 205; Disguise the icmp predicate by commuting the max op to the RHS.206 207define i1 @sgt_smax3(i32 %a, i32 %y) {208; CHECK-LABEL: @sgt_smax3(209; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 3210; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X]]211; CHECK-NEXT:    ret i1 [[CMP2]]212;213  %x = add i32 %a, 3 ; thwart complexity-based canonicalization214  %cmp1 = icmp sgt i32 %x, %y215  %sel = select i1 %cmp1, i32 %x, i32 %y216  %cmp2 = icmp slt i32 %x, %sel217  ret i1 %cmp2218}219 220; Commute max operands.221 222define i1 @sgt_smax4(i32 %a, i32 %y) {223; CHECK-LABEL: @sgt_smax4(224; CHECK-NEXT:    [[X:%.*]] = add i32 [[A:%.*]], 3225; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[Y:%.*]], [[X]]226; CHECK-NEXT:    ret i1 [[CMP2]]227;228  %x = add i32 %a, 3 ; thwart complexity-based canonicalization229  %cmp1 = icmp sgt i32 %y, %x230  %sel = select i1 %cmp1, i32 %y, i32 %x231  %cmp2 = icmp slt i32 %x, %sel232  ret i1 %cmp2233}234 235declare void @use(i1 %c)236 237define void @eq_smax_contextual(i32 %x, i32 %y, i32 %z) {238; CHECK-LABEL: @eq_smax_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.smax.i32(i32 [[X]], i32 [[Y:%.*]])243; CHECK-NEXT:    call void @use(i1 false)244; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y]], [[Z]]245; CHECK-NEXT:    call void @use(i1 [[CMP2]])246; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[Y]], [[Z]]247; CHECK-NEXT:    call void @use(i1 [[CMP3]])248; CHECK-NEXT:    call void @use(i1 true)249; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]250; CHECK-NEXT:    call void @use(i1 [[CMP5]])251; CHECK-NEXT:    [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]252; CHECK-NEXT:    call void @use(i1 [[CMP6]])253; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]254; CHECK-NEXT:    call void @use(i1 [[CMP7]])255; CHECK-NEXT:    [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]256; CHECK-NEXT:    call void @use(i1 [[CMP8]])257; CHECK-NEXT:    [[CMP9:%.*]] = icmp sge i32 [[X]], [[Y]]258; CHECK-NEXT:    call void @use(i1 [[CMP9]])259; CHECK-NEXT:    [[CMP10:%.*]] = icmp slt 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.smax.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_smax_contextual_commuted(i32 %x, i32 %y, i32 %z) {295; CHECK-LABEL: @eq_smax_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.smax.i32(i32 [[Y:%.*]], i32 [[X]])300; CHECK-NEXT:    call void @use(i1 false)301; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y]], [[Z]]302; CHECK-NEXT:    call void @use(i1 [[CMP2]])303; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[Y]], [[Z]]304; CHECK-NEXT:    call void @use(i1 [[CMP3]])305; CHECK-NEXT:    call void @use(i1 true)306; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]307; CHECK-NEXT:    call void @use(i1 [[CMP5]])308; CHECK-NEXT:    [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]309; CHECK-NEXT:    call void @use(i1 [[CMP6]])310; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]311; CHECK-NEXT:    call void @use(i1 [[CMP7]])312; CHECK-NEXT:    [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]313; CHECK-NEXT:    call void @use(i1 [[CMP8]])314; CHECK-NEXT:    [[CMP9:%.*]] = icmp sge i32 [[X]], [[Y]]315; CHECK-NEXT:    call void @use(i1 [[CMP9]])316; CHECK-NEXT:    [[CMP10:%.*]] = icmp slt 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.smax.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 @slt_smax_contextual(i32 %x, i32 %y, i32 %z) {352; CHECK-LABEL: @slt_smax_contextual(353; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Z:%.*]]354; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]355; CHECK:       if:356; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 [[Y:%.*]])357; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[Y]], [[Z]]358; CHECK-NEXT:    call void @use(i1 [[CMP1]])359; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y]], [[Z]]360; CHECK-NEXT:    call void @use(i1 [[CMP2]])361; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[Y]], [[Z]]362; CHECK-NEXT:    call void @use(i1 [[CMP3]])363; CHECK-NEXT:    [[CMP4:%.*]] = icmp sge i32 [[Y]], [[Z]]364; CHECK-NEXT:    call void @use(i1 [[CMP4]])365; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]366; CHECK-NEXT:    call void @use(i1 [[CMP5]])367; CHECK-NEXT:    [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]368; CHECK-NEXT:    call void @use(i1 [[CMP6]])369; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]370; CHECK-NEXT:    call void @use(i1 [[CMP7]])371; CHECK-NEXT:    [[CMP8:%.*]] = icmp uge i32 [[COND]], [[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 void378; CHECK:       end:379; CHECK-NEXT:    ret void380;381  %cmp = icmp slt i32 %x, %z382  br i1 %cmp, label %if, label %end383if:384  %cond = call i32 @llvm.smax.i32(i32 %x, i32 %y)385  %cmp1 = icmp slt i32 %cond, %z386  call void @use(i1 %cmp1)387  %cmp2 = icmp sle i32 %cond, %z388  call void @use(i1 %cmp2)389  %cmp3 = icmp sgt i32 %cond, %z390  call void @use(i1 %cmp3)391  %cmp4 = icmp sge i32 %cond, %z392  call void @use(i1 %cmp4)393  %cmp5 = icmp ult i32 %cond, %z394  call void @use(i1 %cmp5)395  %cmp6 = icmp ule i32 %cond, %z396  call void @use(i1 %cmp6)397  %cmp7 = icmp ugt i32 %cond, %z398  call void @use(i1 %cmp7)399  %cmp8 = icmp uge i32 %cond, %z400  call void @use(i1 %cmp8)401  %cmp9 = icmp eq i32 %cond, %z402  call void @use(i1 %cmp9)403  %cmp10 = icmp ne i32 %cond, %z404  call void @use(i1 %cmp10)405  ret void406end:407  ret void408}409 410define void @slt_smax_contextual_commuted(i32 %x, i32 %y, i32 %z) {411; CHECK-LABEL: @slt_smax_contextual_commuted(412; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Z:%.*]]413; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]414; CHECK:       if:415; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[Y:%.*]], i32 [[X]])416; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 [[Y]], [[Z]]417; CHECK-NEXT:    call void @use(i1 [[CMP1]])418; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[Y]], [[Z]]419; CHECK-NEXT:    call void @use(i1 [[CMP2]])420; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[Y]], [[Z]]421; CHECK-NEXT:    call void @use(i1 [[CMP3]])422; CHECK-NEXT:    [[CMP4:%.*]] = icmp sge i32 [[Y]], [[Z]]423; CHECK-NEXT:    call void @use(i1 [[CMP4]])424; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]425; CHECK-NEXT:    call void @use(i1 [[CMP5]])426; CHECK-NEXT:    [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]427; CHECK-NEXT:    call void @use(i1 [[CMP6]])428; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]429; CHECK-NEXT:    call void @use(i1 [[CMP7]])430; CHECK-NEXT:    [[CMP8:%.*]] = icmp uge i32 [[COND]], [[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 void437; CHECK:       end:438; CHECK-NEXT:    ret void439;440  %cmp = icmp slt i32 %x, %z441  br i1 %cmp, label %if, label %end442if:443  %cond = call i32 @llvm.smax.i32(i32 %y, i32 %x)444  %cmp1 = icmp slt i32 %cond, %z445  call void @use(i1 %cmp1)446  %cmp2 = icmp sle i32 %cond, %z447  call void @use(i1 %cmp2)448  %cmp3 = icmp sgt i32 %cond, %z449  call void @use(i1 %cmp3)450  %cmp4 = icmp sge i32 %cond, %z451  call void @use(i1 %cmp4)452  %cmp5 = icmp ult i32 %cond, %z453  call void @use(i1 %cmp5)454  %cmp6 = icmp ule i32 %cond, %z455  call void @use(i1 %cmp6)456  %cmp7 = icmp ugt i32 %cond, %z457  call void @use(i1 %cmp7)458  %cmp8 = icmp uge i32 %cond, %z459  call void @use(i1 %cmp8)460  %cmp9 = icmp eq i32 %cond, %z461  call void @use(i1 %cmp9)462  %cmp10 = icmp ne i32 %cond, %z463  call void @use(i1 %cmp10)464  ret void465end:466  ret void467}468 469define void @sle_smax_contextual(i32 %x, i32 %y, i32 %z) {470; CHECK-LABEL: @sle_smax_contextual(471; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Z:%.*]]472; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]473; CHECK:       if:474; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.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 [[Y]], [[Z]]478; CHECK-NEXT:    call void @use(i1 [[CMP2]])479; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[Y]], [[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 [[COND]], [[Z]]486; CHECK-NEXT:    call void @use(i1 [[CMP6]])487; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[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 void496; CHECK:       end:497; CHECK-NEXT:    ret void498;499  %cmp = icmp sle i32 %x, %z500  br i1 %cmp, label %if, label %end501if:502  %cond = call i32 @llvm.smax.i32(i32 %x, i32 %y)503  %cmp1 = icmp slt i32 %cond, %z504  call void @use(i1 %cmp1)505  %cmp2 = icmp sle i32 %cond, %z506  call void @use(i1 %cmp2)507  %cmp3 = icmp sgt i32 %cond, %z508  call void @use(i1 %cmp3)509  %cmp4 = icmp sge i32 %cond, %z510  call void @use(i1 %cmp4)511  %cmp5 = icmp ult i32 %cond, %z512  call void @use(i1 %cmp5)513  %cmp6 = icmp ule i32 %cond, %z514  call void @use(i1 %cmp6)515  %cmp7 = icmp ugt i32 %cond, %z516  call void @use(i1 %cmp7)517  %cmp8 = icmp uge i32 %cond, %z518  call void @use(i1 %cmp8)519  %cmp9 = icmp eq i32 %cond, %z520  call void @use(i1 %cmp9)521  %cmp10 = icmp ne i32 %cond, %z522  call void @use(i1 %cmp10)523  ret void524end:525  ret void526}527 528define void @sle_smax_contextual_commuted(i32 %x, i32 %y, i32 %z) {529; CHECK-LABEL: @sle_smax_contextual_commuted(530; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Z:%.*]]531; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]532; CHECK:       if:533; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.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 [[Y]], [[Z]]537; CHECK-NEXT:    call void @use(i1 [[CMP2]])538; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[Y]], [[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 [[COND]], [[Z]]545; CHECK-NEXT:    call void @use(i1 [[CMP6]])546; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[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 void555; CHECK:       end:556; CHECK-NEXT:    ret void557;558  %cmp = icmp sle i32 %x, %z559  br i1 %cmp, label %if, label %end560if:561  %cond = call i32 @llvm.smax.i32(i32 %y, i32 %x)562  %cmp1 = icmp slt i32 %cond, %z563  call void @use(i1 %cmp1)564  %cmp2 = icmp sle i32 %cond, %z565  call void @use(i1 %cmp2)566  %cmp3 = icmp sgt i32 %cond, %z567  call void @use(i1 %cmp3)568  %cmp4 = icmp sge i32 %cond, %z569  call void @use(i1 %cmp4)570  %cmp5 = icmp ult i32 %cond, %z571  call void @use(i1 %cmp5)572  %cmp6 = icmp ule i32 %cond, %z573  call void @use(i1 %cmp6)574  %cmp7 = icmp ugt i32 %cond, %z575  call void @use(i1 %cmp7)576  %cmp8 = icmp uge i32 %cond, %z577  call void @use(i1 %cmp8)578  %cmp9 = icmp eq i32 %cond, %z579  call void @use(i1 %cmp9)580  %cmp10 = icmp ne i32 %cond, %z581  call void @use(i1 %cmp10)582  ret void583end:584  ret void585}586 587define void @sgt_smax_contextual(i32 %x, i32 %y, i32 %z) {588; CHECK-LABEL: @sgt_smax_contextual(589; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Z:%.*]]590; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]591; CHECK:       if:592; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 [[Y:%.*]])593; CHECK-NEXT:    call void @use(i1 false)594; CHECK-NEXT:    call void @use(i1 false)595; CHECK-NEXT:    call void @use(i1 true)596; CHECK-NEXT:    call void @use(i1 true)597; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]598; CHECK-NEXT:    call void @use(i1 [[CMP5]])599; CHECK-NEXT:    [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]600; CHECK-NEXT:    call void @use(i1 [[CMP6]])601; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]602; CHECK-NEXT:    call void @use(i1 [[CMP7]])603; CHECK-NEXT:    [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]604; CHECK-NEXT:    call void @use(i1 [[CMP8]])605; CHECK-NEXT:    call void @use(i1 false)606; CHECK-NEXT:    call void @use(i1 true)607; CHECK-NEXT:    ret void608; CHECK:       end:609; CHECK-NEXT:    ret void610;611  %cmp = icmp sgt i32 %x, %z612  br i1 %cmp, label %if, label %end613if:614  %cond = call i32 @llvm.smax.i32(i32 %x, i32 %y)615  %cmp1 = icmp slt i32 %cond, %z616  call void @use(i1 %cmp1)617  %cmp2 = icmp sle i32 %cond, %z618  call void @use(i1 %cmp2)619  %cmp3 = icmp sgt i32 %cond, %z620  call void @use(i1 %cmp3)621  %cmp4 = icmp sge i32 %cond, %z622  call void @use(i1 %cmp4)623  %cmp5 = icmp ult i32 %cond, %z624  call void @use(i1 %cmp5)625  %cmp6 = icmp ule i32 %cond, %z626  call void @use(i1 %cmp6)627  %cmp7 = icmp ugt i32 %cond, %z628  call void @use(i1 %cmp7)629  %cmp8 = icmp uge i32 %cond, %z630  call void @use(i1 %cmp8)631  %cmp9 = icmp eq i32 %cond, %z632  call void @use(i1 %cmp9)633  %cmp10 = icmp ne i32 %cond, %z634  call void @use(i1 %cmp10)635  ret void636end:637  ret void638}639 640define void @sgt_smax_contextual_commuted(i32 %x, i32 %y, i32 %z) {641; CHECK-LABEL: @sgt_smax_contextual_commuted(642; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Z:%.*]]643; CHECK-NEXT:    br i1 [[CMP]], label [[IF:%.*]], label [[END:%.*]]644; CHECK:       if:645; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[Y:%.*]], i32 [[X]])646; CHECK-NEXT:    call void @use(i1 false)647; CHECK-NEXT:    call void @use(i1 false)648; CHECK-NEXT:    call void @use(i1 true)649; CHECK-NEXT:    call void @use(i1 true)650; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]651; CHECK-NEXT:    call void @use(i1 [[CMP5]])652; CHECK-NEXT:    [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]653; CHECK-NEXT:    call void @use(i1 [[CMP6]])654; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]655; CHECK-NEXT:    call void @use(i1 [[CMP7]])656; CHECK-NEXT:    [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]657; CHECK-NEXT:    call void @use(i1 [[CMP8]])658; CHECK-NEXT:    call void @use(i1 false)659; CHECK-NEXT:    call void @use(i1 true)660; CHECK-NEXT:    ret void661; CHECK:       end:662; CHECK-NEXT:    ret void663;664  %cmp = icmp sgt i32 %x, %z665  br i1 %cmp, label %if, label %end666if:667  %cond = call i32 @llvm.smax.i32(i32 %y, i32 %x)668  %cmp1 = icmp slt i32 %cond, %z669  call void @use(i1 %cmp1)670  %cmp2 = icmp sle i32 %cond, %z671  call void @use(i1 %cmp2)672  %cmp3 = icmp sgt i32 %cond, %z673  call void @use(i1 %cmp3)674  %cmp4 = icmp sge i32 %cond, %z675  call void @use(i1 %cmp4)676  %cmp5 = icmp ult i32 %cond, %z677  call void @use(i1 %cmp5)678  %cmp6 = icmp ule i32 %cond, %z679  call void @use(i1 %cmp6)680  %cmp7 = icmp ugt i32 %cond, %z681  call void @use(i1 %cmp7)682  %cmp8 = icmp uge i32 %cond, %z683  call void @use(i1 %cmp8)684  %cmp9 = icmp eq i32 %cond, %z685  call void @use(i1 %cmp9)686  %cmp10 = icmp ne i32 %cond, %z687  call void @use(i1 %cmp10)688  ret void689end:690  ret void691}692 693define void @sge_smax_contextual(i32 %x, i32 %y, i32 %z) {694; CHECK-LABEL: @sge_smax_contextual(695; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Z:%.*]]696; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]697; CHECK:       if:698; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X]], i32 [[Y:%.*]])699; CHECK-NEXT:    call void @use(i1 false)700; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]701; CHECK-NEXT:    call void @use(i1 [[CMP2]])702; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]703; CHECK-NEXT:    call void @use(i1 [[CMP3]])704; CHECK-NEXT:    call void @use(i1 true)705; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[Z]]706; CHECK-NEXT:    call void @use(i1 [[CMP5]])707; CHECK-NEXT:    [[CMP6:%.*]] = icmp ule i32 [[COND]], [[Z]]708; CHECK-NEXT:    call void @use(i1 [[CMP6]])709; CHECK-NEXT:    [[CMP7:%.*]] = icmp ugt i32 [[COND]], [[Z]]710; CHECK-NEXT:    call void @use(i1 [[CMP7]])711; CHECK-NEXT:    [[CMP8:%.*]] = icmp uge i32 [[COND]], [[Z]]712; CHECK-NEXT:    call void @use(i1 [[CMP8]])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 void718; CHECK:       end:719; CHECK-NEXT:    ret void720;721  %cmp = icmp sge i32 %x, %z722  br i1 %cmp, label %if, label %end723if:724  %cond = call i32 @llvm.smax.i32(i32 %x, i32 %y)725  %cmp1 = icmp slt i32 %cond, %z726  call void @use(i1 %cmp1)727  %cmp2 = icmp sle i32 %cond, %z728  call void @use(i1 %cmp2)729  %cmp3 = icmp sgt i32 %cond, %z730  call void @use(i1 %cmp3)731  %cmp4 = icmp sge i32 %cond, %z732  call void @use(i1 %cmp4)733  %cmp5 = icmp ult i32 %cond, %z734  call void @use(i1 %cmp5)735  %cmp6 = icmp ule i32 %cond, %z736  call void @use(i1 %cmp6)737  %cmp7 = icmp ugt i32 %cond, %z738  call void @use(i1 %cmp7)739  %cmp8 = icmp uge i32 %cond, %z740  call void @use(i1 %cmp8)741  %cmp9 = icmp eq i32 %cond, %z742  call void @use(i1 %cmp9)743  %cmp10 = icmp ne i32 %cond, %z744  call void @use(i1 %cmp10)745  ret void746end:747  ret void748}749 750define void @sge_smax_contextual_commuted(i32 %x, i32 %y, i32 %z) {751; CHECK-LABEL: @sge_smax_contextual_commuted(752; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Z:%.*]]753; CHECK-NEXT:    br i1 [[CMP_NOT]], label [[END:%.*]], label [[IF:%.*]]754; CHECK:       if:755; CHECK-NEXT:    [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[Y:%.*]], i32 [[X]])756; CHECK-NEXT:    call void @use(i1 false)757; CHECK-NEXT:    [[CMP2:%.*]] = icmp sle i32 [[COND]], [[Z]]758; CHECK-NEXT:    call void @use(i1 [[CMP2]])759; CHECK-NEXT:    [[CMP3:%.*]] = icmp sgt i32 [[COND]], [[Z]]760; CHECK-NEXT:    call void @use(i1 [[CMP3]])761; CHECK-NEXT:    call void @use(i1 true)762; CHECK-NEXT:    [[CMP5:%.*]] = icmp ult i32 [[COND]], [[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 [[COND]], [[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 sge i32 %x, %z779  br i1 %cmp, label %if, label %end780if:781  %cond = call i32 @llvm.smax.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 807; Tests from PR76672808 809define i1 @test_smax_ugt(i32 %a) {810; CHECK-LABEL: @test_smax_ugt(811; CHECK-NEXT:  entry:812; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[A:%.*]], 1813; CHECK-NEXT:    ret i1 [[CMP]]814;815entry:816  %cond.i = call i32 @llvm.smax.i32(i32 %a, i32 0)817  %cmp = icmp ugt i32 %cond.i, 1818  ret i1 %cmp819}820 821; Negative tests822 823define i1 @test_smax_ugt_neg1(i32 %a) {824; CHECK-LABEL: @test_smax_ugt_neg1(825; CHECK-NEXT:  entry:826; CHECK-NEXT:    ret i1 false827;828entry:829  %cond.i = call i32 @llvm.smax.i32(i32 %a, i32 0)830  %cmp = icmp ugt i32 %cond.i, -5831  ret i1 %cmp832}833 834define i1 @test_smax_ugt_neg2(i32 %a) {835; CHECK-LABEL: @test_smax_ugt_neg2(836; CHECK-NEXT:  entry:837; CHECK-NEXT:    [[COND_I:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 -5)838; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[COND_I]], 1839; CHECK-NEXT:    ret i1 [[CMP]]840;841entry:842  %cond.i = call i32 @llvm.smax.i32(i32 %a, i32 -5)843  %cmp = icmp ugt i32 %cond.i, 1844  ret i1 %cmp845}846 847 848declare i32 @llvm.smax.i32(i32, i32)849