1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -instcombine < %s | FileCheck %s 3 4; If we have a umin feeding an unsigned or equality icmp that shares an 5; operand with the umin, the compare should always be folded. 6; Test all 4 foldable predicates (eq,ne,uge,ult) * 4 commutation 7; possibilities for each predicate. Note that folds to true/false 8; (predicate is ule/ugt) or folds to an existing instruction should be 9; handled by InstSimplify. 10 11; umin(X, Y) == X --> X <= Y 12 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, %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 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, %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 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, 3 42; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y 43; CHECK-NEXT: ret i1 [[CMP2]] 44; 45 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 46 %cmp1 = icmp ult 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 min operands. 53 54define i1 @eq_umin4(i32 %a, i32 %y) { 55; CHECK-LABEL: @eq_umin4( 56; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 57; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y 58; CHECK-NEXT: ret i1 [[CMP2]] 59; 60 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 61 %cmp1 = icmp ult 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; umin(X, Y) >= X --> X <= Y 68 69define i1 @uge_umin1(i32 %x, i32 %y) { 70; CHECK-LABEL: @uge_umin1( 71; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y 72; CHECK-NEXT: ret i1 [[CMP2]] 73; 74 %cmp1 = icmp ult i32 %x, %y 75 %sel = select i1 %cmp1, i32 %x, i32 %y 76 %cmp2 = icmp uge i32 %sel, %x 77 ret i1 %cmp2 78} 79 80; Commute min operands. 81 82define i1 @uge_umin2(i32 %x, i32 %y) { 83; CHECK-LABEL: @uge_umin2( 84; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 %x, %y 85; CHECK-NEXT: ret i1 [[CMP2]] 86; 87 %cmp1 = icmp ult i32 %y, %x 88 %sel = select i1 %cmp1, i32 %y, i32 %x 89 %cmp2 = icmp uge i32 %sel, %x 90 ret i1 %cmp2 91} 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, 3 98; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y 99; CHECK-NEXT: ret i1 [[CMP2]] 100; 101 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 102 %cmp1 = icmp ult i32 %x, %y 103 %sel = select i1 %cmp1, i32 %x, i32 %y 104 %cmp2 = icmp ule i32 %x, %sel 105 ret i1 %cmp2 106} 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, 3 113; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[X]], %y 114; CHECK-NEXT: ret i1 [[CMP2]] 115; 116 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 117 %cmp1 = icmp ult i32 %y, %x 118 %sel = select i1 %cmp1, i32 %y, i32 %x 119 %cmp2 = icmp ule i32 %x, %sel 120 ret i1 %cmp2 121} 122 123; umin(X, Y) != X --> X > Y 124 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, %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 min operands. 137 138define i1 @ne_umin2(i32 %x, i32 %y) { 139; CHECK-LABEL: @ne_umin2( 140; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x 141; CHECK-NEXT: ret i1 [[CMP1]] 142; 143 %cmp1 = icmp ult 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 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, 3 154; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], %y 155; CHECK-NEXT: ret i1 [[CMP2]] 156; 157 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 158 %cmp1 = icmp ult 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 min operands. 165 166define i1 @ne_umin4(i32 %a, i32 %y) { 167; CHECK-LABEL: @ne_umin4( 168; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 169; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y 170; CHECK-NEXT: ret i1 [[CMP1]] 171; 172 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 173 %cmp1 = icmp ult 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; umin(X, Y) < X --> X > Y 180 181define i1 @ult_umin1(i32 %x, i32 %y) { 182; CHECK-LABEL: @ult_umin1( 183; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 %x, %y 184; CHECK-NEXT: ret i1 [[CMP2]] 185; 186 %cmp1 = icmp ult i32 %x, %y 187 %sel = select i1 %cmp1, i32 %x, i32 %y 188 %cmp2 = icmp ult i32 %sel, %x 189 ret i1 %cmp2 190} 191 192; Commute min operands. 193 194define i1 @ult_umin2(i32 %x, i32 %y) { 195; CHECK-LABEL: @ult_umin2( 196; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 %y, %x 197; CHECK-NEXT: ret i1 [[CMP1]] 198; 199 %cmp1 = icmp ult i32 %y, %x 200 %sel = select i1 %cmp1, i32 %y, i32 %x 201 %cmp2 = icmp ult i32 %sel, %x 202 ret i1 %cmp2 203} 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, 3 210; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt i32 [[X]], %y 211; CHECK-NEXT: ret i1 [[CMP2]] 212; 213 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 214 %cmp1 = icmp ult i32 %x, %y 215 %sel = select i1 %cmp1, i32 %x, i32 %y 216 %cmp2 = icmp ugt i32 %x, %sel 217 ret i1 %cmp2 218} 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, 3 225; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt i32 [[X]], %y 226; CHECK-NEXT: ret i1 [[CMP1]] 227; 228 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 229 %cmp1 = icmp ult i32 %y, %x 230 %sel = select i1 %cmp1, i32 %y, i32 %x 231 %cmp2 = icmp ugt i32 %x, %sel 232 ret i1 %cmp2 233} 234 235