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 an smin feeding a signed or equality icmp that shares an 5; operand with the smin, the compare should always be folded. 6; Test all 6 foldable predicates (eq,ne,sge,sgt,sle,slt) * 4 commutation 7; possibilities for each predicate. Note that folds to true/false or 8; folds to an existing instruction may be handled by InstSimplify. 9 10; smin(X, Y) == X --> X <= Y 11 12define i1 @eq_smin1(i32 %x, i32 %y) { 13; CHECK-LABEL: @eq_smin1( 14; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y 15; CHECK-NEXT: ret i1 [[CMP2]] 16; 17 %cmp1 = icmp slt i32 %x, %y 18 %sel = select i1 %cmp1, i32 %x, i32 %y 19 %cmp2 = icmp eq i32 %sel, %x 20 ret i1 %cmp2 21} 22 23; Commute min operands. 24 25define i1 @eq_smin2(i32 %x, i32 %y) { 26; CHECK-LABEL: @eq_smin2( 27; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y 28; CHECK-NEXT: ret i1 [[CMP2]] 29; 30 %cmp1 = icmp slt i32 %y, %x 31 %sel = select i1 %cmp1, i32 %y, i32 %x 32 %cmp2 = icmp eq i32 %sel, %x 33 ret i1 %cmp2 34} 35 36; Disguise the icmp predicate by commuting the min op to the RHS. 37 38define i1 @eq_smin3(i32 %a, i32 %y) { 39; CHECK-LABEL: @eq_smin3( 40; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 41; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y 42; CHECK-NEXT: ret i1 [[CMP2]] 43; 44 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 45 %cmp1 = icmp slt i32 %x, %y 46 %sel = select i1 %cmp1, i32 %x, i32 %y 47 %cmp2 = icmp eq i32 %x, %sel 48 ret i1 %cmp2 49} 50 51; Commute min operands. 52 53define i1 @eq_smin4(i32 %a, i32 %y) { 54; CHECK-LABEL: @eq_smin4( 55; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 56; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y 57; CHECK-NEXT: ret i1 [[CMP2]] 58; 59 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 60 %cmp1 = icmp slt i32 %y, %x 61 %sel = select i1 %cmp1, i32 %y, i32 %x 62 %cmp2 = icmp eq i32 %x, %sel 63 ret i1 %cmp2 64} 65 66; smin(X, Y) >= X --> X <= Y 67 68define i1 @sge_smin1(i32 %x, i32 %y) { 69; CHECK-LABEL: @sge_smin1( 70; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y 71; CHECK-NEXT: ret i1 [[CMP2]] 72; 73 %cmp1 = icmp slt i32 %x, %y 74 %sel = select i1 %cmp1, i32 %x, i32 %y 75 %cmp2 = icmp sge i32 %sel, %x 76 ret i1 %cmp2 77} 78 79; Commute min operands. 80 81define i1 @sge_smin2(i32 %x, i32 %y) { 82; CHECK-LABEL: @sge_smin2( 83; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 %x, %y 84; CHECK-NEXT: ret i1 [[CMP2]] 85; 86 %cmp1 = icmp slt i32 %y, %x 87 %sel = select i1 %cmp1, i32 %y, i32 %x 88 %cmp2 = icmp sge i32 %sel, %x 89 ret i1 %cmp2 90} 91 92; Disguise the icmp predicate by commuting the min op to the RHS. 93 94define i1 @sge_smin3(i32 %a, i32 %y) { 95; CHECK-LABEL: @sge_smin3( 96; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 97; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y 98; CHECK-NEXT: ret i1 [[CMP2]] 99; 100 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 101 %cmp1 = icmp slt i32 %x, %y 102 %sel = select i1 %cmp1, i32 %x, i32 %y 103 %cmp2 = icmp sle i32 %x, %sel 104 ret i1 %cmp2 105} 106 107; Commute min operands. 108 109define i1 @sge_smin4(i32 %a, i32 %y) { 110; CHECK-LABEL: @sge_smin4( 111; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 112; CHECK-NEXT: [[CMP2:%.*]] = icmp sle i32 [[X]], %y 113; CHECK-NEXT: ret i1 [[CMP2]] 114; 115 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 116 %cmp1 = icmp slt i32 %y, %x 117 %sel = select i1 %cmp1, i32 %y, i32 %x 118 %cmp2 = icmp sle i32 %x, %sel 119 ret i1 %cmp2 120} 121 122; smin(X, Y) != X --> X > Y 123 124define i1 @ne_smin1(i32 %x, i32 %y) { 125; CHECK-LABEL: @ne_smin1( 126; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 %x, %y 127; CHECK-NEXT: ret i1 [[CMP2]] 128; 129 %cmp1 = icmp slt i32 %x, %y 130 %sel = select i1 %cmp1, i32 %x, i32 %y 131 %cmp2 = icmp ne i32 %sel, %x 132 ret i1 %cmp2 133} 134 135; Commute min operands. 136 137define i1 @ne_smin2(i32 %x, i32 %y) { 138; CHECK-LABEL: @ne_smin2( 139; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 %y, %x 140; CHECK-NEXT: ret i1 [[CMP1]] 141; 142 %cmp1 = icmp slt i32 %y, %x 143 %sel = select i1 %cmp1, i32 %y, i32 %x 144 %cmp2 = icmp ne i32 %sel, %x 145 ret i1 %cmp2 146} 147 148; Disguise the icmp predicate by commuting the min op to the RHS. 149 150define i1 @ne_smin3(i32 %a, i32 %y) { 151; CHECK-LABEL: @ne_smin3( 152; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 153; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[X]], %y 154; CHECK-NEXT: ret i1 [[CMP2]] 155; 156 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 157 %cmp1 = icmp slt i32 %x, %y 158 %sel = select i1 %cmp1, i32 %x, i32 %y 159 %cmp2 = icmp ne i32 %x, %sel 160 ret i1 %cmp2 161} 162 163; Commute min operands. 164 165define i1 @ne_smin4(i32 %a, i32 %y) { 166; CHECK-LABEL: @ne_smin4( 167; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 168; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], %y 169; CHECK-NEXT: ret i1 [[CMP1]] 170; 171 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 172 %cmp1 = icmp slt i32 %y, %x 173 %sel = select i1 %cmp1, i32 %y, i32 %x 174 %cmp2 = icmp ne i32 %x, %sel 175 ret i1 %cmp2 176} 177 178; smin(X, Y) < X --> X > Y 179 180define i1 @slt_smin1(i32 %x, i32 %y) { 181; CHECK-LABEL: @slt_smin1( 182; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 %x, %y 183; CHECK-NEXT: ret i1 [[CMP2]] 184; 185 %cmp1 = icmp slt i32 %x, %y 186 %sel = select i1 %cmp1, i32 %x, i32 %y 187 %cmp2 = icmp slt i32 %sel, %x 188 ret i1 %cmp2 189} 190 191; Commute min operands. 192 193define i1 @slt_smin2(i32 %x, i32 %y) { 194; CHECK-LABEL: @slt_smin2( 195; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 %y, %x 196; CHECK-NEXT: ret i1 [[CMP1]] 197; 198 %cmp1 = icmp slt i32 %y, %x 199 %sel = select i1 %cmp1, i32 %y, i32 %x 200 %cmp2 = icmp slt i32 %sel, %x 201 ret i1 %cmp2 202} 203 204; Disguise the icmp predicate by commuting the min op to the RHS. 205 206define i1 @slt_smin3(i32 %a, i32 %y) { 207; CHECK-LABEL: @slt_smin3( 208; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 209; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[X]], %y 210; CHECK-NEXT: ret i1 [[CMP2]] 211; 212 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 213 %cmp1 = icmp slt i32 %x, %y 214 %sel = select i1 %cmp1, i32 %x, i32 %y 215 %cmp2 = icmp sgt i32 %x, %sel 216 ret i1 %cmp2 217} 218 219; Commute min operands. 220 221define i1 @slt_smin4(i32 %a, i32 %y) { 222; CHECK-LABEL: @slt_smin4( 223; CHECK-NEXT: [[X:%.*]] = add i32 %a, 3 224; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[X]], %y 225; CHECK-NEXT: ret i1 [[CMP1]] 226; 227 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 228 %cmp1 = icmp slt i32 %y, %x 229 %sel = select i1 %cmp1, i32 %y, i32 %x 230 %cmp2 = icmp sgt i32 %x, %sel 231 ret i1 %cmp2 232} 233 234; smin(X, Y) <= X --> true 235 236define i1 @sle_smin1(i32 %x, i32 %y) { 237; CHECK-LABEL: @sle_smin1( 238; CHECK-NEXT: ret i1 true 239; 240 %cmp1 = icmp slt i32 %x, %y 241 %sel = select i1 %cmp1, i32 %x, i32 %y 242 %cmp2 = icmp sle i32 %sel, %x 243 ret i1 %cmp2 244} 245 246; Commute min operands. 247 248define i1 @sle_smin2(i32 %x, i32 %y) { 249; CHECK-LABEL: @sle_smin2( 250; CHECK-NEXT: ret i1 true 251; 252 %cmp1 = icmp slt i32 %y, %x 253 %sel = select i1 %cmp1, i32 %y, i32 %x 254 %cmp2 = icmp sle i32 %sel, %x 255 ret i1 %cmp2 256} 257 258; Disguise the icmp predicate by commuting the min op to the RHS. 259 260define i1 @sle_smin3(i32 %a, i32 %y) { 261; CHECK-LABEL: @sle_smin3( 262; CHECK-NEXT: ret i1 true 263; 264 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 265 %cmp1 = icmp slt i32 %x, %y 266 %sel = select i1 %cmp1, i32 %x, i32 %y 267 %cmp2 = icmp sge i32 %x, %sel 268 ret i1 %cmp2 269} 270 271; Commute min operands. 272 273define i1 @sle_smin4(i32 %a, i32 %y) { 274; CHECK-LABEL: @sle_smin4( 275; CHECK-NEXT: ret i1 true 276; 277 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 278 %cmp1 = icmp slt i32 %y, %x 279 %sel = select i1 %cmp1, i32 %y, i32 %x 280 %cmp2 = icmp sge i32 %x, %sel 281 ret i1 %cmp2 282} 283 284; smin(X, Y) > X --> false 285 286define i1 @sgt_smin1(i32 %x, i32 %y) { 287; CHECK-LABEL: @sgt_smin1( 288; CHECK-NEXT: ret i1 false 289; 290 %cmp1 = icmp slt i32 %x, %y 291 %sel = select i1 %cmp1, i32 %x, i32 %y 292 %cmp2 = icmp sgt i32 %sel, %x 293 ret i1 %cmp2 294} 295 296; Commute min operands. 297 298define i1 @sgt_smin2(i32 %x, i32 %y) { 299; CHECK-LABEL: @sgt_smin2( 300; CHECK-NEXT: ret i1 false 301; 302 %cmp1 = icmp slt i32 %y, %x 303 %sel = select i1 %cmp1, i32 %y, i32 %x 304 %cmp2 = icmp sgt i32 %sel, %x 305 ret i1 %cmp2 306} 307 308; Disguise the icmp predicate by commuting the min op to the RHS. 309 310define i1 @sgt_smin3(i32 %a, i32 %y) { 311; CHECK-LABEL: @sgt_smin3( 312; CHECK-NEXT: ret i1 false 313; 314 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 315 %cmp1 = icmp slt i32 %x, %y 316 %sel = select i1 %cmp1, i32 %x, i32 %y 317 %cmp2 = icmp slt i32 %x, %sel 318 ret i1 %cmp2 319} 320 321; Commute min operands. 322 323define i1 @sgt_smin4(i32 %a, i32 %y) { 324; CHECK-LABEL: @sgt_smin4( 325; CHECK-NEXT: ret i1 false 326; 327 %x = add i32 %a, 3 ; thwart complexity-based canonicalization 328 %cmp1 = icmp slt i32 %y, %x 329 %sel = select i1 %cmp1, i32 %y, i32 %x 330 %cmp2 = icmp slt i32 %x, %sel 331 ret i1 %cmp2 332} 333 334