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 13 define 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 26 define 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 39 define 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 54 define 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 69 define 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 82 define 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 95 define 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 110 define 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 125 define 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 138 define 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 151 define 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 166 define 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 181 define 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 194 define 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 207 define 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 222 define 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