1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -passes=instcombine < %s | FileCheck %s 3 4; This is the canonical form for a type-changing min/max. 5define i64 @t1(i32 %a) { 6; CHECK-LABEL: @t1( 7; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 5) 8; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 9; CHECK-NEXT: ret i64 [[TMP2]] 10; 11 %1 = icmp slt i32 %a, 5 12 %2 = select i1 %1, i32 %a, i32 5 13 %3 = sext i32 %2 to i64 14 ret i64 %3 15} 16 17; Check this is converted into canonical form, as above. 18define i64 @t2(i32 %a) { 19; CHECK-LABEL: @t2( 20; CHECK-NEXT: [[NARROW:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 5) 21; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[NARROW]] to i64 22; CHECK-NEXT: ret i64 [[TMP1]] 23; 24 %1 = icmp slt i32 %a, 5 25 %2 = sext i32 %a to i64 26 %3 = select i1 %1, i64 %2, i64 5 27 ret i64 %3 28} 29 30; Same as @t2, with flipped operands and zext instead of sext. 31define i64 @t3(i32 %a) { 32; CHECK-LABEL: @t3( 33; CHECK-NEXT: [[NARROW:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 5) 34; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[NARROW]] to i64 35; CHECK-NEXT: ret i64 [[TMP1]] 36; 37 %1 = icmp ult i32 %a, 5 38 %2 = zext i32 %a to i64 39 %3 = select i1 %1, i64 5, i64 %2 40 ret i64 %3 41} 42 43; Same again, with trunc. 44define i32 @t4(i64 %a) { 45; CHECK-LABEL: @t4( 46; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 5) 47; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 48; CHECK-NEXT: ret i32 [[TMP2]] 49; 50 %1 = icmp slt i64 %a, 5 51 %2 = trunc i64 %a to i32 52 %3 = select i1 %1, i32 %2, i32 5 53 ret i32 %3 54} 55 56; Same as @t3, but with mismatched signedness between icmp and zext. 57define i64 @t5(i32 %a) { 58; CHECK-LABEL: @t5( 59; CHECK-NEXT: [[NARROW:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 5) 60; CHECK-NEXT: [[TMP1:%.*]] = zext nneg i32 [[NARROW]] to i64 61; CHECK-NEXT: ret i64 [[TMP1]] 62; 63 %1 = icmp slt i32 %a, 5 64 %2 = zext i32 %a to i64 65 %3 = select i1 %1, i64 5, i64 %2 66 ret i64 %3 67} 68 69define float @t6(i32 %a) { 70; CHECK-LABEL: @t6( 71; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 0) 72; CHECK-NEXT: [[TMP2:%.*]] = sitofp i32 [[TMP1]] to float 73; CHECK-NEXT: ret float [[TMP2]] 74; 75 %1 = icmp slt i32 %a, 0 76 %2 = select i1 %1, i32 %a, i32 0 77 %3 = sitofp i32 %2 to float 78 ret float %3 79} 80 81define i16 @t7(i32 %a) { 82; CHECK-LABEL: @t7( 83; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 -32768) 84; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i16 85; CHECK-NEXT: ret i16 [[TMP2]] 86; 87 %1 = icmp slt i32 %a, -32768 88 %2 = trunc i32 %a to i16 89 %3 = select i1 %1, i16 %2, i16 -32768 90 ret i16 %3 91} 92 93; Just check for no infinite loop. InstSimplify liked to 94; "simplify" -32767 by removing all the sign bits, 95; which led to a canonicalization fight between different 96; parts of instcombine. 97define i32 @t8(i64 %a, i32 %b) { 98; CHECK-LABEL: @t8( 99; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.smin.i64(i64 [[A:%.*]], i64 -32767) 100; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 101; CHECK-NEXT: [[TMP3:%.*]] = icmp slt i32 [[B:%.*]], 42 102; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[B]], [[TMP2]] 103; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP3]], i1 true, i1 [[TMP4]] 104; CHECK-NEXT: [[TMP6:%.*]] = zext i1 [[TMP5]] to i32 105; CHECK-NEXT: ret i32 [[TMP6]] 106; 107 %1 = icmp slt i64 %a, -32767 108 %2 = select i1 %1, i64 %a, i64 -32767 109 %3 = trunc i64 %2 to i32 110 %4 = icmp slt i32 %b, 42 111 %5 = select i1 %4, i32 42, i32 %3 112 %6 = icmp ne i32 %5, %b 113 %7 = zext i1 %6 to i32 114 ret i32 %7 115} 116 117; Ensure this doesn't get converted to a min/max. 118define i64 @t9(i32 %a) { 119; CHECK-LABEL: @t9( 120; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A:%.*]], -1 121; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[A]] to i64 122; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP1]], i64 [[TMP2]], i64 4294967295 123; CHECK-NEXT: ret i64 [[TMP3]] 124; 125 %1 = icmp sgt i32 %a, -1 126 %2 = sext i32 %a to i64 127 %3 = select i1 %1, i64 %2, i64 4294967295 128 ret i64 %3 129} 130 131define float @t10(i32 %x) { 132; CHECK-LABEL: @t10( 133; CHECK-NEXT: [[R1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 255) 134; CHECK-NEXT: [[R:%.*]] = uitofp nneg i32 [[R1]] to float 135; CHECK-NEXT: ret float [[R]] 136; 137 %f_x = sitofp i32 %x to float 138 %cmp = icmp sgt i32 %x, 255 139 %r = select i1 %cmp, float %f_x, float 255.0 140 ret float %r 141} 142 143define float @t11(i64 %x) { 144; CHECK-LABEL: @t11( 145; CHECK-NEXT: [[R1:%.*]] = call i64 @llvm.smax.i64(i64 [[X:%.*]], i64 255) 146; CHECK-NEXT: [[R:%.*]] = uitofp nneg i64 [[R1]] to float 147; CHECK-NEXT: ret float [[R]] 148; 149 %f_x = sitofp i64 %x to float 150 %cmp = icmp sgt i64 %x, 255 151 %r = select i1 %cmp, float %f_x, float 255.0 152 ret float %r 153} 154 155; Reuse the first 2 bitcasts as the select operands. 156 157define <4 x i32> @bitcasts_fcmp_1(<2 x i64> %a, <2 x i64> %b) { 158; CHECK-LABEL: @bitcasts_fcmp_1( 159; CHECK-NEXT: [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float> 160; CHECK-NEXT: [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x float> 161; CHECK-NEXT: [[T2:%.*]] = fcmp olt <4 x float> [[T1]], [[T0]] 162; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[T2]], <4 x float> [[T0]], <4 x float> [[T1]] 163; CHECK-NEXT: [[T5:%.*]] = bitcast <4 x float> [[TMP1]] to <4 x i32> 164; CHECK-NEXT: ret <4 x i32> [[T5]] 165; 166 %t0 = bitcast <2 x i64> %a to <4 x float> 167 %t1 = bitcast <2 x i64> %b to <4 x float> 168 %t2 = fcmp olt <4 x float> %t1, %t0 169 %t3 = bitcast <2 x i64> %a to <4 x i32> 170 %t4 = bitcast <2 x i64> %b to <4 x i32> 171 %t5 = select <4 x i1> %t2, <4 x i32> %t3, <4 x i32> %t4 172 ret <4 x i32> %t5 173} 174 175; Switch cmp operand order. 176 177define <4 x i32> @bitcasts_fcmp_2(<2 x i64> %a, <2 x i64> %b) { 178; CHECK-LABEL: @bitcasts_fcmp_2( 179; CHECK-NEXT: [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x float> 180; CHECK-NEXT: [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x float> 181; CHECK-NEXT: [[T2:%.*]] = fcmp olt <4 x float> [[T0]], [[T1]] 182; CHECK-NEXT: [[TMP1:%.*]] = select <4 x i1> [[T2]], <4 x float> [[T0]], <4 x float> [[T1]] 183; CHECK-NEXT: [[T5:%.*]] = bitcast <4 x float> [[TMP1]] to <4 x i32> 184; CHECK-NEXT: ret <4 x i32> [[T5]] 185; 186 %t0 = bitcast <2 x i64> %a to <4 x float> 187 %t1 = bitcast <2 x i64> %b to <4 x float> 188 %t2 = fcmp olt <4 x float> %t0, %t1 189 %t3 = bitcast <2 x i64> %a to <4 x i32> 190 %t4 = bitcast <2 x i64> %b to <4 x i32> 191 %t5 = select <4 x i1> %t2, <4 x i32> %t3, <4 x i32> %t4 192 ret <4 x i32> %t5 193} 194 195; Integer cmp should have the same transforms. 196 197define <4 x float> @bitcasts_icmp(<2 x i64> %a, <2 x i64> %b) { 198; CHECK-LABEL: @bitcasts_icmp( 199; CHECK-NEXT: [[T0:%.*]] = bitcast <2 x i64> [[A:%.*]] to <4 x i32> 200; CHECK-NEXT: [[T1:%.*]] = bitcast <2 x i64> [[B:%.*]] to <4 x i32> 201; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[T1]], <4 x i32> [[T0]]) 202; CHECK-NEXT: [[T5:%.*]] = bitcast <4 x i32> [[TMP1]] to <4 x float> 203; CHECK-NEXT: ret <4 x float> [[T5]] 204; 205 %t0 = bitcast <2 x i64> %a to <4 x i32> 206 %t1 = bitcast <2 x i64> %b to <4 x i32> 207 %t2 = icmp slt <4 x i32> %t1, %t0 208 %t3 = bitcast <2 x i64> %a to <4 x float> 209 %t4 = bitcast <2 x i64> %b to <4 x float> 210 %t5 = select <4 x i1> %t2, <4 x float> %t3, <4 x float> %t4 211 ret <4 x float> %t5 212} 213 214; SMIN(SMIN(X, 11), 92) -> SMIN(X, 11) 215define i32 @test68(i32 %x) { 216; CHECK-LABEL: @test68( 217; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 11) 218; CHECK-NEXT: ret i32 [[COND]] 219; 220 %cmp = icmp slt i32 11, %x 221 %cond = select i1 %cmp, i32 11, i32 %x 222 %cmp3 = icmp slt i32 92, %cond 223 %retval = select i1 %cmp3, i32 92, i32 %cond 224 ret i32 %retval 225} 226 227define <2 x i32> @test68vec(<2 x i32> %x) { 228; CHECK-LABEL: @test68vec( 229; CHECK-NEXT: [[COND:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 11)) 230; CHECK-NEXT: ret <2 x i32> [[COND]] 231; 232 %cmp = icmp slt <2 x i32> <i32 11, i32 11>, %x 233 %cond = select <2 x i1> %cmp, <2 x i32> <i32 11, i32 11>, <2 x i32> %x 234 %cmp3 = icmp slt <2 x i32> <i32 92, i32 92>, %cond 235 %retval = select <2 x i1> %cmp3, <2 x i32> <i32 92, i32 92>, <2 x i32> %cond 236 ret <2 x i32> %retval 237} 238 239; MIN(MIN(X, 24), 83) -> MIN(X, 24) 240define i32 @test69(i32 %x) { 241; CHECK-LABEL: @test69( 242; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 24) 243; CHECK-NEXT: ret i32 [[COND]] 244; 245 %cmp = icmp ult i32 24, %x 246 %cond = select i1 %cmp, i32 24, i32 %x 247 %cmp3 = icmp ult i32 83, %cond 248 %retval = select i1 %cmp3, i32 83, i32 %cond 249 ret i32 %retval 250} 251 252; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75) 253define i32 @test70(i32 %x) { 254; CHECK-LABEL: @test70( 255; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 75) 256; CHECK-NEXT: ret i32 [[COND]] 257; 258 %cmp = icmp slt i32 %x, 75 259 %cond = select i1 %cmp, i32 75, i32 %x 260 %cmp3 = icmp slt i32 %cond, 36 261 %retval = select i1 %cmp3, i32 36, i32 %cond 262 ret i32 %retval 263} 264 265; MAX(MAX(X, 68), 47) -> MAX(X, 68) 266define i32 @test71(i32 %x) { 267; CHECK-LABEL: @test71( 268; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 68) 269; CHECK-NEXT: ret i32 [[COND]] 270; 271 %cmp = icmp ult i32 %x, 68 272 %cond = select i1 %cmp, i32 68, i32 %x 273 %cmp3 = icmp ult i32 %cond, 47 274 %retval = select i1 %cmp3, i32 47, i32 %cond 275 ret i32 %retval 276} 277 278; SMIN(SMIN(X, 92), 11) -> SMIN(X, 11) 279define i32 @test72(i32 %x) { 280; CHECK-LABEL: @test72( 281; CHECK-NEXT: [[RETVAL:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 11) 282; CHECK-NEXT: ret i32 [[RETVAL]] 283; 284 %cmp = icmp sgt i32 %x, 92 285 %cond = select i1 %cmp, i32 92, i32 %x 286 %cmp3 = icmp sgt i32 %cond, 11 287 %retval = select i1 %cmp3, i32 11, i32 %cond 288 ret i32 %retval 289} 290 291define <2 x i32> @test72vec(<2 x i32> %x) { 292; CHECK-LABEL: @test72vec( 293; CHECK-NEXT: [[RETVAL:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 11)) 294; CHECK-NEXT: ret <2 x i32> [[RETVAL]] 295; 296 %cmp = icmp sgt <2 x i32> %x, <i32 92, i32 92> 297 %cond = select <2 x i1> %cmp, <2 x i32> <i32 92, i32 92>, <2 x i32> %x 298 %cmp3 = icmp sgt <2 x i32> %cond, <i32 11, i32 11> 299 %retval = select <2 x i1> %cmp3, <2 x i32> <i32 11, i32 11>, <2 x i32> %cond 300 ret <2 x i32> %retval 301} 302 303; MIN(MIN(X, 83), 24) -> MIN(X, 24) 304define i32 @test73(i32 %x) { 305; CHECK-LABEL: @test73( 306; CHECK-NEXT: [[RETVAL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 24) 307; CHECK-NEXT: ret i32 [[RETVAL]] 308; 309 %cmp = icmp ugt i32 %x, 83 310 %cond = select i1 %cmp, i32 83, i32 %x 311 %cmp3 = icmp ugt i32 %cond, 24 312 %retval = select i1 %cmp3, i32 24, i32 %cond 313 ret i32 %retval 314} 315 316; SMAX(SMAX(X, 36), 75) -> SMAX(X, 75) 317define i32 @test74(i32 %x) { 318; CHECK-LABEL: @test74( 319; CHECK-NEXT: [[RETVAL:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 75) 320; CHECK-NEXT: ret i32 [[RETVAL]] 321; 322 %cmp = icmp slt i32 %x, 36 323 %cond = select i1 %cmp, i32 36, i32 %x 324 %cmp3 = icmp slt i32 %cond, 75 325 %retval = select i1 %cmp3, i32 75, i32 %cond 326 ret i32 %retval 327} 328 329; MAX(MAX(X, 47), 68) -> MAX(X, 68) 330define i32 @test75(i32 %x) { 331; CHECK-LABEL: @test75( 332; CHECK-NEXT: [[RETVAL:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 68) 333; CHECK-NEXT: ret i32 [[RETVAL]] 334; 335 %cmp = icmp ult i32 %x, 47 336 %cond = select i1 %cmp, i32 47, i32 %x 337 %cmp3 = icmp ult i32 %cond, 68 338 %retval = select i1 %cmp3, i32 68, i32 %cond 339 ret i32 %retval 340} 341 342; The next 10 tests are value clamping with constants: 343; https://llvm.org/bugs/show_bug.cgi?id=31693 344 345; (X <s C1) ? C1 : SMIN(X, C2) ==> SMAX(SMIN(X, C2), C1) 346 347define i32 @clamp_signed1(i32 %x) { 348; CHECK-LABEL: @clamp_signed1( 349; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) 350; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 15) 351; CHECK-NEXT: ret i32 [[R]] 352; 353 %cmp2 = icmp slt i32 %x, 255 354 %min = select i1 %cmp2, i32 %x, i32 255 355 %cmp1 = icmp slt i32 %x, 15 356 %r = select i1 %cmp1, i32 15, i32 %min 357 ret i32 %r 358} 359 360; (X >s C1) ? C1 : SMAX(X, C2) ==> SMIN(SMAX(X, C2), C1) 361 362define i32 @clamp_signed2(i32 %x) { 363; CHECK-LABEL: @clamp_signed2( 364; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 15) 365; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[MAX]], i32 255) 366; CHECK-NEXT: ret i32 [[R]] 367; 368 %cmp2 = icmp sgt i32 %x, 15 369 %max = select i1 %cmp2, i32 %x, i32 15 370 %cmp1 = icmp sgt i32 %x, 255 371 %r = select i1 %cmp1, i32 255, i32 %max 372 ret i32 %r 373} 374 375; (X >s C1) ? SMIN(X, C2) : C1 ==> SMAX(SMIN(X, C2), C1) 376 377define i32 @clamp_signed3(i32 %x) { 378; CHECK-LABEL: @clamp_signed3( 379; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) 380; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN]], i32 15) 381; CHECK-NEXT: ret i32 [[R]] 382; 383 %cmp2 = icmp slt i32 %x, 255 384 %min = select i1 %cmp2, i32 %x, i32 255 385 %cmp1 = icmp sgt i32 %x, 15 386 %r = select i1 %cmp1, i32 %min, i32 15 387 ret i32 %r 388} 389 390; (X <s C1) ? SMAX(X, C2) : C1 ==> SMIN(SMAX(X, C1), C2) 391 392define i32 @clamp_signed4(i32 %x) { 393; CHECK-LABEL: @clamp_signed4( 394; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 15) 395; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[MAX]], i32 255) 396; CHECK-NEXT: ret i32 [[R]] 397; 398 %cmp2 = icmp sgt i32 %x, 15 399 %max = select i1 %cmp2, i32 %x, i32 15 400 %cmp1 = icmp slt i32 %x, 255 401 %r = select i1 %cmp1, i32 %max, i32 255 402 ret i32 %r 403} 404 405; (X <u C1) ? C1 : UMIN(X, C2) ==> UMAX(UMIN(X, C2), C1) 406 407define i32 @clamp_unsigned1(i32 %x) { 408; CHECK-LABEL: @clamp_unsigned1( 409; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255) 410; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN]], i32 15) 411; CHECK-NEXT: ret i32 [[R]] 412; 413 %cmp2 = icmp ult i32 %x, 255 414 %min = select i1 %cmp2, i32 %x, i32 255 415 %cmp1 = icmp ult i32 %x, 15 416 %r = select i1 %cmp1, i32 15, i32 %min 417 ret i32 %r 418} 419 420; (X >u C1) ? C1 : UMAX(X, C2) ==> UMIN(UMAX(X, C2), C1) 421 422define i32 @clamp_unsigned2(i32 %x) { 423; CHECK-LABEL: @clamp_unsigned2( 424; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 15) 425; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[MAX]], i32 255) 426; CHECK-NEXT: ret i32 [[R]] 427; 428 %cmp2 = icmp ugt i32 %x, 15 429 %max = select i1 %cmp2, i32 %x, i32 15 430 %cmp1 = icmp ugt i32 %x, 255 431 %r = select i1 %cmp1, i32 255, i32 %max 432 ret i32 %r 433} 434 435; (X >u C1) ? UMIN(X, C2) : C1 ==> UMAX(UMIN(X, C2), C1) 436 437define i32 @clamp_unsigned3(i32 %x) { 438; CHECK-LABEL: @clamp_unsigned3( 439; CHECK-NEXT: [[MIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255) 440; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN]], i32 15) 441; CHECK-NEXT: ret i32 [[R]] 442; 443 %cmp2 = icmp ult i32 %x, 255 444 %min = select i1 %cmp2, i32 %x, i32 255 445 %cmp1 = icmp ugt i32 %x, 15 446 %r = select i1 %cmp1, i32 %min, i32 15 447 ret i32 %r 448} 449 450; (X <u C1) ? UMAX(X, C2) : C1 ==> UMIN(UMAX(X, C2), C1) 451 452define i32 @clamp_unsigned4(i32 %x) { 453; CHECK-LABEL: @clamp_unsigned4( 454; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 15) 455; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[MAX]], i32 255) 456; CHECK-NEXT: ret i32 [[R]] 457; 458 %cmp2 = icmp ugt i32 %x, 15 459 %max = select i1 %cmp2, i32 %x, i32 15 460 %cmp1 = icmp ult i32 %x, 255 461 %r = select i1 %cmp1, i32 %max, i32 255 462 ret i32 %r 463} 464 465; Check that clamp is recognized and there is no infinite 466; loop because of reverse cmp transformation: 467; (icmp sgt smin(PositiveA, B) 0) -> (icmp sgt B 0) 468define i32 @clamp_check_for_no_infinite_loop1(i32 %i) { 469; CHECK-LABEL: @clamp_check_for_no_infinite_loop1( 470; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smin.i32(i32 [[I:%.*]], i32 255) 471; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.smax.i32(i32 [[SEL1]], i32 0) 472; CHECK-NEXT: ret i32 [[RES]] 473; 474 %cmp1 = icmp slt i32 %i, 255 475 %sel1 = select i1 %cmp1, i32 %i, i32 255 476 %cmp2 = icmp slt i32 %i, 0 477 %res = select i1 %cmp2, i32 0, i32 %sel1 478 ret i32 %res 479} 480; Check that there is no infinite loop in case of: 481; (icmp slt smax(NegativeA, B) 0) -> (icmp slt B 0) 482define i32 @clamp_check_for_no_infinite_loop2(i32 %i) { 483; CHECK-LABEL: @clamp_check_for_no_infinite_loop2( 484; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smax.i32(i32 [[I:%.*]], i32 -255) 485; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.smin.i32(i32 [[SEL1]], i32 0) 486; CHECK-NEXT: ret i32 [[RES]] 487; 488 %cmp1 = icmp sgt i32 %i, -255 489 %sel1 = select i1 %cmp1, i32 %i, i32 -255 490 %cmp2 = icmp slt i32 %i, 0 491 %res = select i1 %cmp2, i32 %sel1, i32 0 492 ret i32 %res 493} 494 495; Check that there is no infinite loop because of reverse cmp transformation: 496; (icmp slt smax(PositiveA, B) 2) -> (icmp eq B 1) 497define i32 @clamp_check_for_no_infinite_loop3(i32 %i) { 498; CHECK-LABEL: @clamp_check_for_no_infinite_loop3( 499; CHECK-NEXT: br i1 true, label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]] 500; CHECK: truelabel: 501; CHECK-NEXT: [[I3:%.*]] = call i32 @llvm.smax.i32(i32 [[I:%.*]], i32 1) 502; CHECK-NEXT: [[I6:%.*]] = call i32 @llvm.umin.i32(i32 [[I3]], i32 2) 503; CHECK-NEXT: [[I7:%.*]] = shl nuw nsw i32 [[I6]], 2 504; CHECK-NEXT: ret i32 [[I7]] 505; CHECK: falselabel: 506; CHECK-NEXT: ret i32 0 507; 508 509 %i2 = icmp sgt i32 %i, 1 510 %i3 = select i1 %i2, i32 %i, i32 1 511 %i4 = icmp sgt i32 %i3, 0 512 br i1 %i4, label %truelabel, label %falselabel 513 514truelabel: ; %i<=1, %i3>0 515 %i5 = icmp slt i32 %i3, 2 516 %i6 = select i1 %i5, i32 %i3, i32 2 517 %i7 = shl nuw nsw i32 %i6, 2 518 ret i32 %i7 519 520falselabel: 521 ret i32 0 522} 523 524; The next 3 min tests should canonicalize to the same form...and not infinite loop. 525 526define double @PR31751_umin1(i32 %x) { 527; CHECK-LABEL: @PR31751_umin1( 528; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) 529; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double 530; CHECK-NEXT: ret double [[CONV]] 531; 532 %cmp = icmp slt i32 %x, 0 533 %sel = select i1 %cmp, i32 2147483647, i32 %x 534 %conv = sitofp i32 %sel to double 535 ret double %conv 536} 537 538define double @PR31751_umin2(i32 %x) { 539; CHECK-LABEL: @PR31751_umin2( 540; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) 541; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double 542; CHECK-NEXT: ret double [[CONV]] 543; 544 %cmp = icmp ult i32 %x, 2147483647 545 %sel = select i1 %cmp, i32 %x, i32 2147483647 546 %conv = sitofp i32 %sel to double 547 ret double %conv 548} 549 550define double @PR31751_umin3(i32 %x) { 551; CHECK-LABEL: @PR31751_umin3( 552; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) 553; CHECK-NEXT: [[CONV:%.*]] = uitofp nneg i32 [[SEL]] to double 554; CHECK-NEXT: ret double [[CONV]] 555; 556 %cmp = icmp ugt i32 %x, 2147483647 557 %sel = select i1 %cmp, i32 2147483647, i32 %x 558 %conv = sitofp i32 %sel to double 559 ret double %conv 560} 561 562; The next 3 max tests should canonicalize to the same form...and not infinite loop. 563 564define double @PR31751_umax1(i32 %x) { 565; CHECK-LABEL: @PR31751_umax1( 566; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648) 567; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double 568; CHECK-NEXT: ret double [[CONV]] 569; 570 %cmp = icmp sgt i32 %x, -1 571 %sel = select i1 %cmp, i32 2147483648, i32 %x 572 %conv = sitofp i32 %sel to double 573 ret double %conv 574} 575 576define double @PR31751_umax2(i32 %x) { 577; CHECK-LABEL: @PR31751_umax2( 578; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648) 579; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double 580; CHECK-NEXT: ret double [[CONV]] 581; 582 %cmp = icmp ugt i32 %x, 2147483648 583 %sel = select i1 %cmp, i32 %x, i32 2147483648 584 %conv = sitofp i32 %sel to double 585 ret double %conv 586} 587 588define double @PR31751_umax3(i32 %x) { 589; CHECK-LABEL: @PR31751_umax3( 590; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648) 591; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[SEL]] to double 592; CHECK-NEXT: ret double [[CONV]] 593; 594 %cmp = icmp ult i32 %x, 2147483648 595 %sel = select i1 %cmp, i32 2147483648, i32 %x 596 %conv = sitofp i32 %sel to double 597 ret double %conv 598} 599 600; The icmp/select form a canonical smax, so don't hide that by folding the final bitcast into the select. 601 602define float @bitcast_scalar_smax(float %x, float %y) { 603; CHECK-LABEL: @bitcast_scalar_smax( 604; CHECK-NEXT: [[BCX:%.*]] = bitcast float [[X:%.*]] to i32 605; CHECK-NEXT: [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32 606; CHECK-NEXT: [[SEL:%.*]] = call i32 @llvm.smax.i32(i32 [[BCX]], i32 [[BCY]]) 607; CHECK-NEXT: [[BCS:%.*]] = bitcast i32 [[SEL]] to float 608; CHECK-NEXT: ret float [[BCS]] 609; 610 %bcx = bitcast float %x to i32 611 %bcy = bitcast float %y to i32 612 %cmp = icmp sgt i32 %bcx, %bcy 613 %sel = select i1 %cmp, i32 %bcx, i32 %bcy 614 %bcs = bitcast i32 %sel to float 615 ret float %bcs 616} 617 618; FIXME: Create a canonical umax by bitcasting the select. 619 620define float @bitcast_scalar_umax(float %x, float %y) { 621; CHECK-LABEL: @bitcast_scalar_umax( 622; CHECK-NEXT: [[BCX:%.*]] = bitcast float [[X:%.*]] to i32 623; CHECK-NEXT: [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32 624; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[BCX]], [[BCY]] 625; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[Y]] 626; CHECK-NEXT: ret float [[SEL]] 627; 628 %bcx = bitcast float %x to i32 629 %bcy = bitcast float %y to i32 630 %cmp = icmp ugt i32 %bcx, %bcy 631 %sel = select i1 %cmp, float %x, float %y 632 ret float %sel 633} 634 635; PR32306 - https://bugs.llvm.org/show_bug.cgi?id=32306 636; The icmp/select form a canonical smin, so don't hide that by folding the final bitcast into the select. 637 638define <8 x float> @bitcast_vector_smin(<8 x float> %x, <8 x float> %y) { 639; CHECK-LABEL: @bitcast_vector_smin( 640; CHECK-NEXT: [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32> 641; CHECK-NEXT: [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32> 642; CHECK-NEXT: [[SEL:%.*]] = call <8 x i32> @llvm.smin.v8i32(<8 x i32> [[BCX]], <8 x i32> [[BCY]]) 643; CHECK-NEXT: [[BCS:%.*]] = bitcast <8 x i32> [[SEL]] to <8 x float> 644; CHECK-NEXT: ret <8 x float> [[BCS]] 645; 646 %bcx = bitcast <8 x float> %x to <8 x i32> 647 %bcy = bitcast <8 x float> %y to <8 x i32> 648 %cmp = icmp slt <8 x i32> %bcx, %bcy 649 %sel = select <8 x i1> %cmp, <8 x i32> %bcx, <8 x i32> %bcy 650 %bcs = bitcast <8 x i32> %sel to <8 x float> 651 ret <8 x float> %bcs 652} 653 654; FIXME: Create a canonical umin by bitcasting the select. 655 656define <8 x float> @bitcast_vector_umin(<8 x float> %x, <8 x float> %y) { 657; CHECK-LABEL: @bitcast_vector_umin( 658; CHECK-NEXT: [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32> 659; CHECK-NEXT: [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32> 660; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i32> [[BCX]], [[BCY]] 661; CHECK-NEXT: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x float> [[X]], <8 x float> [[Y]] 662; CHECK-NEXT: ret <8 x float> [[SEL]] 663; 664 %bcx = bitcast <8 x float> %x to <8 x i32> 665 %bcy = bitcast <8 x float> %y to <8 x i32> 666 %cmp = icmp slt <8 x i32> %bcx, %bcy 667 %sel = select <8 x i1> %cmp, <8 x float> %x, <8 x float> %y 668 ret <8 x float> %sel 669} 670 671; Check that we look through cast and recognize min idiom. 672 673define zeroext i8 @look_through_cast1(i32 %x) { 674; CHECK-LABEL: @look_through_cast1( 675; CHECK-NEXT: [[RES1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 511) 676; CHECK-NEXT: [[RES:%.*]] = trunc i32 [[RES1]] to i8 677; CHECK-NEXT: ret i8 [[RES]] 678; 679 %cmp1 = icmp slt i32 %x, 511 680 %x_trunc = trunc i32 %x to i8 681 %res = select i1 %cmp1, i8 %x_trunc, i8 255 682 ret i8 %res 683} 684 685; Check that we look through cast but min is not recognized. 686 687define zeroext i8 @look_through_cast2(i32 %x) { 688; CHECK-LABEL: @look_through_cast2( 689; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 510 690; CHECK-NEXT: [[X_TRUNC:%.*]] = trunc i32 [[X]] to i8 691; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP1]], i8 [[X_TRUNC]], i8 -1 692; CHECK-NEXT: ret i8 [[RES]] 693; 694 %cmp1 = icmp slt i32 %x, 510 695 %x_trunc = trunc i32 %x to i8 696 %res = select i1 %cmp1, i8 %x_trunc, i8 255 697 ret i8 %res 698} 699 700define i8 @look_through_cast_int_min(i8 %a, i32 %min) { 701; CHECK-LABEL: @look_through_cast_int_min( 702; CHECK-NEXT: [[A32:%.*]] = sext i8 [[A:%.*]] to i32 703; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smin.i32(i32 [[MIN:%.*]], i32 [[A32]]) 704; CHECK-NEXT: [[SEL:%.*]] = trunc i32 [[SEL1]] to i8 705; CHECK-NEXT: ret i8 [[SEL]] 706; 707 %a32 = sext i8 %a to i32 708 %cmp = icmp slt i32 %a32, %min 709 %min8 = trunc i32 %min to i8 710 %sel = select i1 %cmp, i8 %a, i8 %min8 711 ret i8 %sel 712} 713 714define i16 @look_through_cast_int_max(i16 %a, i32 %max) { 715; CHECK-LABEL: @look_through_cast_int_max( 716; CHECK-NEXT: [[A32:%.*]] = zext i16 [[A:%.*]] to i32 717; CHECK-NEXT: [[SEL1:%.*]] = call i32 @llvm.smax.i32(i32 [[MAX:%.*]], i32 [[A32]]) 718; CHECK-NEXT: [[SEL:%.*]] = trunc i32 [[SEL1]] to i16 719; CHECK-NEXT: ret i16 [[SEL]] 720; 721 %a32 = zext i16 %a to i32 722 %cmp = icmp sgt i32 %max, %a32 723 %max8 = trunc i32 %max to i16 724 %sel = select i1 %cmp, i16 %max8, i16 %a 725 ret i16 %sel 726} 727 728define <2 x i8> @min_through_cast_vec1(<2 x i32> %x) { 729; CHECK-LABEL: @min_through_cast_vec1( 730; CHECK-NEXT: [[RES1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 510, i32 511>) 731; CHECK-NEXT: [[RES:%.*]] = trunc <2 x i32> [[RES1]] to <2 x i8> 732; CHECK-NEXT: ret <2 x i8> [[RES]] 733; 734 %cmp = icmp slt <2 x i32> %x, <i32 510, i32 511> 735 %x_trunc = trunc <2 x i32> %x to <2 x i8> 736 %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 254, i8 255> 737 ret <2 x i8> %res 738} 739 740define <2 x i8> @min_through_cast_vec2(<2 x i32> %x) { 741; CHECK-LABEL: @min_through_cast_vec2( 742; CHECK-NEXT: [[RES1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 511)) 743; CHECK-NEXT: [[RES:%.*]] = trunc <2 x i32> [[RES1]] to <2 x i8> 744; CHECK-NEXT: ret <2 x i8> [[RES]] 745; 746 %cmp = icmp slt <2 x i32> %x, <i32 511, i32 511> 747 %x_trunc = trunc <2 x i32> %x to <2 x i8> 748 %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 255, i8 255> 749 ret <2 x i8> %res 750} 751 752define <8 x i8> @look_through_cast_int_min_vec(<8 x i8> %a, <8 x i32> %min) { 753; CHECK-LABEL: @look_through_cast_int_min_vec( 754; CHECK-NEXT: [[A32:%.*]] = sext <8 x i8> [[A:%.*]] to <8 x i32> 755; CHECK-NEXT: [[SEL1:%.*]] = call <8 x i32> @llvm.umin.v8i32(<8 x i32> [[MIN:%.*]], <8 x i32> [[A32]]) 756; CHECK-NEXT: [[SEL:%.*]] = trunc <8 x i32> [[SEL1]] to <8 x i8> 757; CHECK-NEXT: ret <8 x i8> [[SEL]] 758; 759 %a32 = sext <8 x i8> %a to <8 x i32> 760 %cmp = icmp ult <8 x i32> %a32, %min 761 %min8 = trunc <8 x i32> %min to <8 x i8> 762 %sel = select <8 x i1> %cmp, <8 x i8> %a, <8 x i8> %min8 763 ret <8 x i8> %sel 764} 765 766define <8 x i32> @look_through_cast_int_max_vec(<8 x i32> %a, <8 x i64> %max) { 767; CHECK-LABEL: @look_through_cast_int_max_vec( 768; CHECK-NEXT: [[A32:%.*]] = zext <8 x i32> [[A:%.*]] to <8 x i64> 769; CHECK-NEXT: [[SEL1:%.*]] = call <8 x i64> @llvm.smax.v8i64(<8 x i64> [[MAX:%.*]], <8 x i64> [[A32]]) 770; CHECK-NEXT: [[SEL:%.*]] = trunc <8 x i64> [[SEL1]] to <8 x i32> 771; CHECK-NEXT: ret <8 x i32> [[SEL]] 772; 773 %a32 = zext <8 x i32> %a to <8 x i64> 774 %cmp = icmp sgt <8 x i64> %a32, %max 775 %max8 = trunc <8 x i64> %max to <8 x i32> 776 %sel = select <8 x i1> %cmp, <8 x i32> %a, <8 x i32> %max8 777 ret <8 x i32> %sel 778} 779 780; Remove a min/max op in a sequence with a common operand. 781; PR35717: https://bugs.llvm.org/show_bug.cgi?id=35717 782 783; min(min(a, b), min(b, c)) --> min(min(a, b), c) 784 785define i32 @common_factor_smin(i32 %a, i32 %b, i32 %c) { 786; CHECK-LABEL: @common_factor_smin( 787; CHECK-NEXT: [[MIN_BC:%.*]] = call i32 @llvm.smin.i32(i32 [[B:%.*]], i32 [[C:%.*]]) 788; CHECK-NEXT: [[MIN_ABC:%.*]] = call i32 @llvm.smin.i32(i32 [[MIN_BC]], i32 [[A:%.*]]) 789; CHECK-NEXT: ret i32 [[MIN_ABC]] 790; 791 %cmp_ab = icmp slt i32 %a, %b 792 %min_ab = select i1 %cmp_ab, i32 %a, i32 %b 793 %cmp_bc = icmp slt i32 %b, %c 794 %min_bc = select i1 %cmp_bc, i32 %b, i32 %c 795 %cmp_ab_bc = icmp slt i32 %min_ab, %min_bc 796 %min_abc = select i1 %cmp_ab_bc, i32 %min_ab, i32 %min_bc 797 ret i32 %min_abc 798} 799 800; max(max(a, b), max(c, b)) --> max(max(a, b), c) 801 802define <2 x i32> @common_factor_smax(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { 803; CHECK-LABEL: @common_factor_smax( 804; CHECK-NEXT: [[MAX_CB:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[C:%.*]], <2 x i32> [[B:%.*]]) 805; CHECK-NEXT: [[MAX_ABC:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[MAX_CB]], <2 x i32> [[A:%.*]]) 806; CHECK-NEXT: ret <2 x i32> [[MAX_ABC]] 807; 808 %cmp_ab = icmp sgt <2 x i32> %a, %b 809 %max_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b 810 %cmp_cb = icmp sgt <2 x i32> %c, %b 811 %max_cb = select <2 x i1> %cmp_cb, <2 x i32> %c, <2 x i32> %b 812 %cmp_ab_cb = icmp sgt <2 x i32> %max_ab, %max_cb 813 %max_abc = select <2 x i1> %cmp_ab_cb, <2 x i32> %max_ab, <2 x i32> %max_cb 814 ret <2 x i32> %max_abc 815} 816 817; min(min(b, c), min(a, b)) --> min(min(b, c), a) 818 819define <2 x i32> @common_factor_umin(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { 820; CHECK-LABEL: @common_factor_umin( 821; CHECK-NEXT: [[MIN_AB:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 822; CHECK-NEXT: [[MIN_ABC:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[MIN_AB]], <2 x i32> [[C:%.*]]) 823; CHECK-NEXT: ret <2 x i32> [[MIN_ABC]] 824; 825 %cmp_bc = icmp ult <2 x i32> %b, %c 826 %min_bc = select <2 x i1> %cmp_bc, <2 x i32> %b, <2 x i32> %c 827 %cmp_ab = icmp ult <2 x i32> %a, %b 828 %min_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b 829 %cmp_bc_ab = icmp ult <2 x i32> %min_bc, %min_ab 830 %min_abc = select <2 x i1> %cmp_bc_ab, <2 x i32> %min_bc, <2 x i32> %min_ab 831 ret <2 x i32> %min_abc 832} 833 834; max(max(b, c), max(b, a)) --> max(max(b, c), a) 835 836define i32 @common_factor_umax(i32 %a, i32 %b, i32 %c) { 837; CHECK-LABEL: @common_factor_umax( 838; CHECK-NEXT: [[MAX_BA:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 839; CHECK-NEXT: [[MAX_ABC:%.*]] = call i32 @llvm.umax.i32(i32 [[MAX_BA]], i32 [[C:%.*]]) 840; CHECK-NEXT: ret i32 [[MAX_ABC]] 841; 842 %cmp_bc = icmp ugt i32 %b, %c 843 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 844 %cmp_ba = icmp ugt i32 %b, %a 845 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 846 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 847 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 848 ret i32 %max_abc 849} 850 851declare void @extra_use(i32) 852 853define i32 @common_factor_umax_extra_use_lhs(i32 %a, i32 %b, i32 %c) { 854; CHECK-LABEL: @common_factor_umax_extra_use_lhs( 855; CHECK-NEXT: [[MAX_BC:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[C:%.*]]) 856; CHECK-NEXT: [[MAX_ABC:%.*]] = call i32 @llvm.umax.i32(i32 [[MAX_BC]], i32 [[A:%.*]]) 857; CHECK-NEXT: call void @extra_use(i32 [[MAX_BC]]) 858; CHECK-NEXT: ret i32 [[MAX_ABC]] 859; 860 %cmp_bc = icmp ugt i32 %b, %c 861 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 862 %cmp_ba = icmp ugt i32 %b, %a 863 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 864 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 865 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 866 call void @extra_use(i32 %max_bc) 867 ret i32 %max_abc 868} 869 870define i32 @common_factor_umax_extra_use_rhs(i32 %a, i32 %b, i32 %c) { 871; CHECK-LABEL: @common_factor_umax_extra_use_rhs( 872; CHECK-NEXT: [[MAX_BA:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 873; CHECK-NEXT: [[MAX_ABC:%.*]] = call i32 @llvm.umax.i32(i32 [[MAX_BA]], i32 [[C:%.*]]) 874; CHECK-NEXT: call void @extra_use(i32 [[MAX_BA]]) 875; CHECK-NEXT: ret i32 [[MAX_ABC]] 876; 877 %cmp_bc = icmp ugt i32 %b, %c 878 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 879 %cmp_ba = icmp ugt i32 %b, %a 880 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 881 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 882 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 883 call void @extra_use(i32 %max_ba) 884 ret i32 %max_abc 885} 886 887define i32 @common_factor_umax_extra_use_both(i32 %a, i32 %b, i32 %c) { 888; CHECK-LABEL: @common_factor_umax_extra_use_both( 889; CHECK-NEXT: [[MAX_BC:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[C:%.*]]) 890; CHECK-NEXT: [[MAX_BA:%.*]] = call i32 @llvm.umax.i32(i32 [[B]], i32 [[A:%.*]]) 891; CHECK-NEXT: [[MAX_ABC:%.*]] = call i32 @llvm.umax.i32(i32 [[MAX_BC]], i32 [[MAX_BA]]) 892; CHECK-NEXT: call void @extra_use(i32 [[MAX_BC]]) 893; CHECK-NEXT: call void @extra_use(i32 [[MAX_BA]]) 894; CHECK-NEXT: ret i32 [[MAX_ABC]] 895; 896 %cmp_bc = icmp ugt i32 %b, %c 897 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 898 %cmp_ba = icmp ugt i32 %b, %a 899 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 900 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 901 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 902 call void @extra_use(i32 %max_bc) 903 call void @extra_use(i32 %max_ba) 904 ret i32 %max_abc 905} 906 907; This would assert. Don't assume that earlier min/max types match a possible later min/max. 908 909define float @not_min_of_min(i8 %i, float %x) { 910; CHECK-LABEL: @not_min_of_min( 911; CHECK-NEXT: [[MIN1:%.*]] = call fast float @llvm.minnum.f32(float [[X:%.*]], float 1.000000e+00) 912; CHECK-NEXT: [[MIN2:%.*]] = call fast float @llvm.minnum.f32(float [[X]], float 2.000000e+00) 913; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[I:%.*]], 16 914; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP3]], float [[MIN1]], float [[MIN2]] 915; CHECK-NEXT: ret float [[R]] 916; 917 %cmp1 = fcmp fast ult float %x, 1.0 918 %min1 = select i1 %cmp1, float %x, float 1.0 919 %cmp2 = fcmp fast ult float %x, 2.0 920 %min2 = select i1 %cmp2, float %x, float 2.0 921 %cmp3 = icmp ult i8 %i, 16 922 %r = select i1 %cmp3, float %min1, float %min2 923 ret float %r 924} 925 926define i32 @add_umin(i32 %x) { 927; CHECK-LABEL: @add_umin( 928; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 27) 929; CHECK-NEXT: [[R:%.*]] = add nuw nsw i32 [[TMP1]], 15 930; CHECK-NEXT: ret i32 [[R]] 931; 932 %a = add nuw i32 %x, 15 933 %c = icmp ult i32 %a, 42 934 %r = select i1 %c, i32 %a, i32 42 935 ret i32 %r 936} 937 938define i32 @add_umin_constant_limit(i32 %x) { 939; CHECK-LABEL: @add_umin_constant_limit( 940; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[X:%.*]], 0 941; CHECK-NEXT: [[R:%.*]] = select i1 [[DOTNOT]], i32 41, i32 42 942; CHECK-NEXT: ret i32 [[R]] 943; 944 %a = add nuw i32 %x, 41 945 %c = icmp ult i32 %a, 42 946 %r = select i1 %c, i32 %a, i32 42 947 ret i32 %r 948} 949 950; Negative test 951; TODO: assert that instsimplify always gets this? 952 953define i32 @add_umin_simplify(i32 %x) { 954; CHECK-LABEL: @add_umin_simplify( 955; CHECK-NEXT: ret i32 42 956; 957 %a = add nuw i32 %x, 42 958 %c = icmp ult i32 %a, 42 959 %r = select i1 %c, i32 %a, i32 42 960 ret i32 %r 961} 962 963; Negative test 964; TODO: assert that instsimplify always gets this? 965 966define i32 @add_umin_simplify2(i32 %x) { 967; CHECK-LABEL: @add_umin_simplify2( 968; CHECK-NEXT: ret i32 42 969; 970 %a = add nuw i32 %x, 43 971 %c = icmp ult i32 %a, 42 972 %r = select i1 %c, i32 %a, i32 42 973 ret i32 %r 974} 975 976; Negative test 977 978define i32 @add_umin_wrong_pred(i32 %x) { 979; CHECK-LABEL: @add_umin_wrong_pred( 980; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 981; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42) 982; CHECK-NEXT: ret i32 [[R]] 983; 984 %a = add nuw i32 %x, 15 985 %c = icmp slt i32 %a, 42 986 %r = select i1 %c, i32 %a, i32 42 987 ret i32 %r 988} 989 990; Negative test 991 992define i32 @add_umin_wrong_wrap(i32 %x) { 993; CHECK-LABEL: @add_umin_wrong_wrap( 994; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 995; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42) 996; CHECK-NEXT: ret i32 [[R]] 997; 998 %a = add nsw i32 %x, 15 999 %c = icmp ult i32 %a, 42 1000 %r = select i1 %c, i32 %a, i32 42 1001 ret i32 %r 1002} 1003 1004; Negative test 1005 1006define i32 @add_umin_extra_use(i32 %x, ptr %p) { 1007; CHECK-LABEL: @add_umin_extra_use( 1008; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1009; CHECK-NEXT: store i32 [[A]], ptr [[P:%.*]], align 4 1010; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42) 1011; CHECK-NEXT: ret i32 [[R]] 1012; 1013 %a = add nuw i32 %x, 15 1014 store i32 %a, ptr %p 1015 %c = icmp ult i32 %a, 42 1016 %r = select i1 %c, i32 %a, i32 42 1017 ret i32 %r 1018} 1019 1020define <2 x i16> @add_umin_vec(<2 x i16> %x) { 1021; CHECK-LABEL: @add_umin_vec( 1022; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> splat (i16 225)) 1023; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i16> [[TMP1]], splat (i16 15) 1024; CHECK-NEXT: ret <2 x i16> [[R]] 1025; 1026 %a = add nuw <2 x i16> %x, <i16 15, i16 15> 1027 %c = icmp ult <2 x i16> %a, <i16 240, i16 240> 1028 %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240> 1029 ret <2 x i16> %r 1030} 1031 1032define i37 @add_umax(i37 %x) { 1033; CHECK-LABEL: @add_umax( 1034; CHECK-NEXT: [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 37) 1035; CHECK-NEXT: [[R:%.*]] = add nuw i37 [[TMP1]], 5 1036; CHECK-NEXT: ret i37 [[R]] 1037; 1038 %a = add nuw i37 %x, 5 1039 %c = icmp ugt i37 %a, 42 1040 %r = select i1 %c, i37 %a, i37 42 1041 ret i37 %r 1042} 1043 1044define i37 @add_umax_constant_limit(i37 %x) { 1045; CHECK-LABEL: @add_umax_constant_limit( 1046; CHECK-NEXT: [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 1) 1047; CHECK-NEXT: [[R:%.*]] = add nuw i37 [[TMP1]], 81 1048; CHECK-NEXT: ret i37 [[R]] 1049; 1050 %a = add nuw i37 %x, 81 1051 %c = icmp ugt i37 %a, 82 1052 %r = select i1 %c, i37 %a, i37 82 1053 ret i37 %r 1054} 1055 1056; Negative test 1057; TODO: assert that instsimplify always gets this? 1058 1059define i37 @add_umax_simplify(i37 %x) { 1060; CHECK-LABEL: @add_umax_simplify( 1061; CHECK-NEXT: [[A:%.*]] = add nuw i37 [[X:%.*]], 42 1062; CHECK-NEXT: ret i37 [[A]] 1063; 1064 %a = add nuw i37 %x, 42 1065 %c = icmp ugt i37 %a, 42 1066 %r = select i1 %c, i37 %a, i37 42 1067 ret i37 %r 1068} 1069 1070; Negative test 1071; TODO: assert that instsimplify always gets this? 1072 1073define i32 @add_umax_simplify2(i32 %x) { 1074; CHECK-LABEL: @add_umax_simplify2( 1075; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 57 1076; CHECK-NEXT: ret i32 [[A]] 1077; 1078 %a = add nuw i32 %x, 57 1079 %c = icmp ugt i32 %a, 56 1080 %r = select i1 %c, i32 %a, i32 56 1081 ret i32 %r 1082} 1083 1084; Negative test 1085 1086define i32 @add_umax_wrong_pred(i32 %x) { 1087; CHECK-LABEL: @add_umax_wrong_pred( 1088; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1089; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42) 1090; CHECK-NEXT: ret i32 [[R]] 1091; 1092 %a = add nuw i32 %x, 15 1093 %c = icmp sgt i32 %a, 42 1094 %r = select i1 %c, i32 %a, i32 42 1095 ret i32 %r 1096} 1097 1098; Negative test 1099 1100; Without the nuw that would allow pushing the add through the umax, the 1101; add + icmp ugt combination can be interpreted as a range check, and would 1102; normally be canonicalized to use ult instead. However, this is not done when 1103; used as part of a umax to avoid breaking the SPF pattern. 1104define i32 @add_umax_wrong_wrap(i32 %x) { 1105; CHECK-LABEL: @add_umax_wrong_wrap( 1106; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1107; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42) 1108; CHECK-NEXT: ret i32 [[R]] 1109; 1110 %a = add nsw i32 %x, 15 1111 %c = icmp ugt i32 %a, 42 1112 %r = select i1 %c, i32 %a, i32 42 1113 ret i32 %r 1114} 1115 1116; Negative test 1117 1118define i32 @add_umax_extra_use(i32 %x, ptr %p) { 1119; CHECK-LABEL: @add_umax_extra_use( 1120; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1121; CHECK-NEXT: store i32 [[A]], ptr [[P:%.*]], align 4 1122; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42) 1123; CHECK-NEXT: ret i32 [[R]] 1124; 1125 %a = add nuw i32 %x, 15 1126 store i32 %a, ptr %p 1127 %c = icmp ugt i32 %a, 42 1128 %r = select i1 %c, i32 %a, i32 42 1129 ret i32 %r 1130} 1131 1132define <2 x i33> @add_umax_vec(<2 x i33> %x) { 1133; CHECK-LABEL: @add_umax_vec( 1134; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i33> @llvm.umax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> splat (i33 235)) 1135; CHECK-NEXT: [[R:%.*]] = add nuw <2 x i33> [[TMP1]], splat (i33 5) 1136; CHECK-NEXT: ret <2 x i33> [[R]] 1137; 1138 %a = add nuw <2 x i33> %x, <i33 5, i33 5> 1139 %c = icmp ugt <2 x i33> %a, <i33 240, i33 240> 1140 %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240> 1141 ret <2 x i33> %r 1142} 1143 1144define i8 @PR14613_umin(i8 %x) { 1145; CHECK-LABEL: @PR14613_umin( 1146; CHECK-NEXT: [[NARROW:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 15) 1147; CHECK-NEXT: ret i8 [[NARROW]] 1148; 1149 %u4 = zext i8 %x to i32 1150 %u5 = add nuw nsw i32 %u4, 15 1151 %u6 = icmp ult i32 %u5, 255 1152 %u7 = select i1 %u6, i32 %u5, i32 255 1153 %r = trunc i32 %u7 to i8 1154 ret i8 %r 1155} 1156 1157define i8 @PR14613_umax(i8 %x) { 1158; CHECK-LABEL: @PR14613_umax( 1159; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 -16) 1160; CHECK-NEXT: [[U7:%.*]] = add nsw i8 [[TMP1]], 15 1161; CHECK-NEXT: ret i8 [[U7]] 1162; 1163 %u4 = zext i8 %x to i32 1164 %u5 = add nuw nsw i32 %u4, 15 1165 %u6 = icmp ugt i32 %u5, 255 1166 %u7 = select i1 %u6, i32 %u5, i32 255 1167 %r = trunc i32 %u7 to i8 1168 ret i8 %r 1169} 1170 1171define i32 @add_smin(i32 %x) { 1172; CHECK-LABEL: @add_smin( 1173; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 27) 1174; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], 15 1175; CHECK-NEXT: ret i32 [[R]] 1176; 1177 %a = add nsw i32 %x, 15 1178 %c = icmp slt i32 %a, 42 1179 %r = select i1 %c, i32 %a, i32 42 1180 ret i32 %r 1181} 1182 1183define i32 @add_smin_constant_limit(i32 %x) { 1184; CHECK-LABEL: @add_smin_constant_limit( 1185; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 2147483646) 1186; CHECK-NEXT: [[R:%.*]] = add nsw i32 [[TMP1]], -3 1187; CHECK-NEXT: ret i32 [[R]] 1188; 1189 %a = add nsw i32 %x, -3 1190 %c = icmp slt i32 %a, 2147483643 1191 %r = select i1 %c, i32 %a, i32 2147483643 1192 ret i32 %r 1193} 1194 1195; Negative test 1196; TODO: assert that instsimplify always gets this? 1197 1198define i32 @add_smin_simplify(i32 %x) { 1199; CHECK-LABEL: @add_smin_simplify( 1200; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], -3 1201; CHECK-NEXT: ret i32 [[A]] 1202; 1203 %a = add nsw i32 %x, -3 1204 %c = icmp slt i32 %a, 2147483644 1205 %r = select i1 %c, i32 %a, i32 2147483644 1206 ret i32 %r 1207} 1208 1209; Negative test 1210; TODO: assert that instsimplify always gets this? 1211 1212define i32 @add_smin_simplify2(i32 %x) { 1213; CHECK-LABEL: @add_smin_simplify2( 1214; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], -3 1215; CHECK-NEXT: ret i32 [[A]] 1216; 1217 %a = add nsw i32 %x, -3 1218 %c = icmp slt i32 %a, 2147483645 1219 %r = select i1 %c, i32 %a, i32 2147483645 1220 ret i32 %r 1221} 1222 1223; Negative test 1224 1225define i32 @add_smin_wrong_pred(i32 %x) { 1226; CHECK-LABEL: @add_smin_wrong_pred( 1227; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1228; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42) 1229; CHECK-NEXT: ret i32 [[R]] 1230; 1231 %a = add nsw i32 %x, 15 1232 %c = icmp ult i32 %a, 42 1233 %r = select i1 %c, i32 %a, i32 42 1234 ret i32 %r 1235} 1236 1237; Negative test 1238 1239define i32 @add_smin_wrong_wrap(i32 %x) { 1240; CHECK-LABEL: @add_smin_wrong_wrap( 1241; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1242; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42) 1243; CHECK-NEXT: ret i32 [[R]] 1244; 1245 %a = add nuw i32 %x, 15 1246 %c = icmp slt i32 %a, 42 1247 %r = select i1 %c, i32 %a, i32 42 1248 ret i32 %r 1249} 1250 1251; Negative test 1252 1253define i32 @add_smin_extra_use(i32 %x, ptr %p) { 1254; CHECK-LABEL: @add_smin_extra_use( 1255; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1256; CHECK-NEXT: store i32 [[A]], ptr [[P:%.*]], align 4 1257; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42) 1258; CHECK-NEXT: ret i32 [[R]] 1259; 1260 %a = add nsw i32 %x, 15 1261 store i32 %a, ptr %p 1262 %c = icmp slt i32 %a, 42 1263 %r = select i1 %c, i32 %a, i32 42 1264 ret i32 %r 1265} 1266 1267define <2 x i16> @add_smin_vec(<2 x i16> %x) { 1268; CHECK-LABEL: @add_smin_vec( 1269; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> splat (i16 225)) 1270; CHECK-NEXT: [[R:%.*]] = add nsw <2 x i16> [[TMP1]], splat (i16 15) 1271; CHECK-NEXT: ret <2 x i16> [[R]] 1272; 1273 %a = add nsw <2 x i16> %x, <i16 15, i16 15> 1274 %c = icmp slt <2 x i16> %a, <i16 240, i16 240> 1275 %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240> 1276 ret <2 x i16> %r 1277} 1278 1279define i37 @add_smax(i37 %x) { 1280; CHECK-LABEL: @add_smax( 1281; CHECK-NEXT: [[TMP1:%.*]] = call i37 @llvm.smax.i37(i37 [[X:%.*]], i37 37) 1282; CHECK-NEXT: [[R:%.*]] = add nuw nsw i37 [[TMP1]], 5 1283; CHECK-NEXT: ret i37 [[R]] 1284; 1285 %a = add nsw i37 %x, 5 1286 %c = icmp sgt i37 %a, 42 1287 %r = select i1 %c, i37 %a, i37 42 1288 ret i37 %r 1289} 1290 1291define i8 @add_smax_constant_limit(i8 %x) { 1292; CHECK-LABEL: @add_smax_constant_limit( 1293; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127) 1294; CHECK-NEXT: [[R:%.*]] = add nsw i8 [[TMP1]], 125 1295; CHECK-NEXT: ret i8 [[R]] 1296; 1297 %a = add nsw i8 %x, 125 1298 %c = icmp sgt i8 %a, -2 1299 %r = select i1 %c, i8 %a, i8 -2 1300 ret i8 %r 1301} 1302 1303; Negative test 1304; TODO: assert that instsimplify always gets this? 1305 1306define i8 @add_smax_simplify(i8 %x) { 1307; CHECK-LABEL: @add_smax_simplify( 1308; CHECK-NEXT: [[A:%.*]] = add nsw i8 [[X:%.*]], 126 1309; CHECK-NEXT: ret i8 [[A]] 1310; 1311 %a = add nsw i8 %x, 126 1312 %c = icmp sgt i8 %a, -2 1313 %r = select i1 %c, i8 %a, i8 -2 1314 ret i8 %r 1315} 1316 1317; Negative test 1318; TODO: assert that instsimplify always gets this? 1319 1320define i8 @add_smax_simplify2(i8 %x) { 1321; CHECK-LABEL: @add_smax_simplify2( 1322; CHECK-NEXT: [[A:%.*]] = add nsw i8 [[X:%.*]], 127 1323; CHECK-NEXT: ret i8 [[A]] 1324; 1325 %a = add nsw i8 %x, 127 1326 %c = icmp sgt i8 %a, -2 1327 %r = select i1 %c, i8 %a, i8 -2 1328 ret i8 %r 1329} 1330 1331; Negative test 1332 1333define i32 @add_smax_wrong_pred(i32 %x) { 1334; CHECK-LABEL: @add_smax_wrong_pred( 1335; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1336; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42) 1337; CHECK-NEXT: ret i32 [[R]] 1338; 1339 %a = add nsw i32 %x, 15 1340 %c = icmp ugt i32 %a, 42 1341 %r = select i1 %c, i32 %a, i32 42 1342 ret i32 %r 1343} 1344 1345; Negative test 1346 1347define i32 @add_smax_wrong_wrap(i32 %x) { 1348; CHECK-LABEL: @add_smax_wrong_wrap( 1349; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1350; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42) 1351; CHECK-NEXT: ret i32 [[R]] 1352; 1353 %a = add nuw i32 %x, 15 1354 %c = icmp sgt i32 %a, 42 1355 %r = select i1 %c, i32 %a, i32 42 1356 ret i32 %r 1357} 1358 1359; Negative test 1360 1361define i32 @add_smax_extra_use(i32 %x, ptr %p) { 1362; CHECK-LABEL: @add_smax_extra_use( 1363; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1364; CHECK-NEXT: store i32 [[A]], ptr [[P:%.*]], align 4 1365; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42) 1366; CHECK-NEXT: ret i32 [[R]] 1367; 1368 %a = add nsw i32 %x, 15 1369 store i32 %a, ptr %p 1370 %c = icmp sgt i32 %a, 42 1371 %r = select i1 %c, i32 %a, i32 42 1372 ret i32 %r 1373} 1374 1375define <2 x i33> @add_smax_vec(<2 x i33> %x) { 1376; CHECK-LABEL: @add_smax_vec( 1377; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i33> @llvm.smax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> splat (i33 235)) 1378; CHECK-NEXT: [[R:%.*]] = add nuw nsw <2 x i33> [[TMP1]], splat (i33 5) 1379; CHECK-NEXT: ret <2 x i33> [[R]] 1380; 1381 %a = add nsw <2 x i33> %x, <i33 5, i33 5> 1382 %c = icmp sgt <2 x i33> %a, <i33 240, i33 240> 1383 %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240> 1384 ret <2 x i33> %r 1385} 1386 1387define i8 @PR14613_smin(i8 %x) { 1388; CHECK-LABEL: @PR14613_smin( 1389; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 40) 1390; CHECK-NEXT: [[NARROW:%.*]] = add nsw i8 [[TMP1]], 15 1391; CHECK-NEXT: ret i8 [[NARROW]] 1392; 1393 %u4 = sext i8 %x to i32 1394 %u5 = add nuw nsw i32 %u4, 15 1395 %u6 = icmp slt i32 %u5, 55 1396 %u7 = select i1 %u6, i32 %u5, i32 55 1397 %r = trunc i32 %u7 to i8 1398 ret i8 %r 1399} 1400 1401define i8 @PR14613_smax(i8 %x) { 1402; CHECK-LABEL: @PR14613_smax( 1403; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 40) 1404; CHECK-NEXT: [[NARROW:%.*]] = add nuw i8 [[TMP1]], 15 1405; CHECK-NEXT: ret i8 [[NARROW]] 1406; 1407 %u4 = sext i8 %x to i32 1408 %u5 = add nuw nsw i32 %u4, 15 1409 %u6 = icmp sgt i32 %u5, 55 1410 %u7 = select i1 %u6, i32 %u5, i32 55 1411 %r = trunc i32 %u7 to i8 1412 ret i8 %r 1413} 1414 1415define i8 @PR46271(<2 x i8> %x) { 1416; CHECK-LABEL: @PR46271( 1417; CHECK-NEXT: [[NOT:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 -1)) 1418; CHECK-NEXT: [[R:%.*]] = extractelement <2 x i8> [[NOT]], i64 1 1419; CHECK-NEXT: [[R1:%.*]] = xor i8 [[R]], -1 1420; CHECK-NEXT: ret i8 [[R1]] 1421; 1422 %a = icmp sgt <2 x i8> %x, <i8 -1, i8 -1> 1423 %b = select <2 x i1> %a, <2 x i8> %x, <2 x i8> <i8 poison, i8 -1> 1424 %not = xor <2 x i8> %b, <i8 poison, i8 -1> 1425 %r = extractelement <2 x i8> %not, i32 1 1426 ret i8 %r 1427} 1428 1429define i32 @twoway_clamp_lt(i32 %num) { 1430; CHECK-LABEL: @twoway_clamp_lt( 1431; CHECK-NEXT: entry: 1432; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[NUM:%.*]], 13767 1433; CHECK-NEXT: [[R:%.*]] = select i1 [[TMP0]], i32 13768, i32 13767 1434; CHECK-NEXT: ret i32 [[R]] 1435; 1436entry: 1437 %cmp1 = icmp slt i32 %num, 13768 1438 %s1 = select i1 %cmp1, i32 %num, i32 13768 1439 %cmp2 = icmp sgt i32 %s1, 13767 1440 %r = select i1 %cmp2, i32 %s1, i32 13767 1441 ret i32 %r 1442} 1443 1444define i32 @twoway_clamp_gt(i32 %num) { 1445; CHECK-LABEL: @twoway_clamp_gt( 1446; CHECK-NEXT: entry: 1447; CHECK-NEXT: [[S1:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 13767) 1448; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[S1]], i32 13768) 1449; CHECK-NEXT: ret i32 [[R]] 1450; 1451entry: 1452 %cmp1 = icmp sgt i32 %num, 13767 1453 %s1 = select i1 %cmp1, i32 %num, i32 13767 1454 %cmp2 = icmp slt i32 %s1, 13768 1455 %r = select i1 %cmp2, i32 %s1, i32 13768 1456 ret i32 %r 1457} 1458 1459define i32 @twoway_clamp_gt_nonconst(i32 %num, i32 %k) { 1460; CHECK-LABEL: @twoway_clamp_gt_nonconst( 1461; CHECK-NEXT: entry: 1462; CHECK-NEXT: [[K1:%.*]] = add i32 [[K:%.*]], 1 1463; CHECK-NEXT: [[S1:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 [[K]]) 1464; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[S1]], i32 [[K1]]) 1465; CHECK-NEXT: ret i32 [[R]] 1466; 1467entry: 1468 %k1 = add i32 %k, 1 1469 %cmp1 = icmp sgt i32 %num, %k 1470 %s1 = select i1 %cmp1, i32 %num, i32 %k 1471 %cmp2 = icmp slt i32 %s1, %k1 1472 %r = select i1 %cmp2, i32 %s1, i32 %k1 1473 ret i32 %r 1474} 1475 1476define i32 @test_umax_smax1(i32 %x) { 1477; CHECK-LABEL: @test_umax_smax1( 1478; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 1) 1479; CHECK-NEXT: ret i32 [[UMAX]] 1480; 1481 %smax = call i32 @llvm.smax.i32(i32 %x, i32 0) 1482 %umax = call i32 @llvm.umax.i32(i32 %smax, i32 1) 1483 ret i32 %umax 1484} 1485 1486define i32 @test_umax_smax2(i32 %x) { 1487; CHECK-LABEL: @test_umax_smax2( 1488; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 20) 1489; CHECK-NEXT: ret i32 [[SMAX]] 1490; 1491 %smax = call i32 @llvm.smax.i32(i32 %x, i32 20) 1492 %umax = call i32 @llvm.umax.i32(i32 %smax, i32 10) 1493 ret i32 %umax 1494} 1495 1496define <2 x i32> @test_umax_smax_vec(<2 x i32> %x) { 1497; CHECK-LABEL: @test_umax_smax_vec( 1498; CHECK-NEXT: [[UMAX:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 1, i32 20>) 1499; CHECK-NEXT: ret <2 x i32> [[UMAX]] 1500; 1501 %smax = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %x, <2 x i32> <i32 0, i32 20>) 1502 %umax = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %smax, <2 x i32> <i32 1, i32 10>) 1503 ret <2 x i32> %umax 1504} 1505 1506define i32 @test_smin_umin1(i32 %x) { 1507; CHECK-LABEL: @test_smin_umin1( 1508; CHECK-NEXT: [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 10) 1509; CHECK-NEXT: ret i32 [[SMIN]] 1510; 1511 %smin = call i32 @llvm.umin.i32(i32 %x, i32 10) 1512 %umin = call i32 @llvm.smin.i32(i32 %smin, i32 20) 1513 ret i32 %umin 1514} 1515 1516define i32 @test_smin_umin2(i32 %x) { 1517; CHECK-LABEL: @test_smin_umin2( 1518; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 10) 1519; CHECK-NEXT: ret i32 [[UMIN]] 1520; 1521 %smin = call i32 @llvm.umin.i32(i32 %x, i32 20) 1522 %umin = call i32 @llvm.smin.i32(i32 %smin, i32 10) 1523 ret i32 %umin 1524} 1525 1526define <2 x i32> @test_smin_umin_vec(<2 x i32> %x) { 1527; CHECK-LABEL: @test_smin_umin_vec( 1528; CHECK-NEXT: [[UMIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 10)) 1529; CHECK-NEXT: ret <2 x i32> [[UMIN]] 1530; 1531 %smin = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %x, <2 x i32> <i32 10, i32 20>) 1532 %umin = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %smin, <2 x i32> <i32 20, i32 10>) 1533 ret <2 x i32> %umin 1534} 1535 1536; Negative tests 1537 1538define i32 @test_umax_smax3(i32 %x) { 1539; CHECK-LABEL: @test_umax_smax3( 1540; CHECK-NEXT: ret i32 -1 1541; 1542 %smax = call i32 @llvm.smax.i32(i32 %x, i32 0) 1543 %umax = call i32 @llvm.umax.i32(i32 %smax, i32 -1) 1544 ret i32 %umax 1545} 1546 1547define i32 @test_umax_smax4(i32 %x) { 1548; CHECK-LABEL: @test_umax_smax4( 1549; CHECK-NEXT: [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -20) 1550; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SMAX]], i32 10) 1551; CHECK-NEXT: ret i32 [[UMAX]] 1552; 1553 %smax = call i32 @llvm.smax.i32(i32 %x, i32 -20) 1554 %umax = call i32 @llvm.umax.i32(i32 %smax, i32 10) 1555 ret i32 %umax 1556} 1557 1558define i32 @test_smin_umin3(i32 %x) { 1559; CHECK-LABEL: @test_smin_umin3( 1560; CHECK-NEXT: ret i32 -20 1561; 1562 %smin = call i32 @llvm.umin.i32(i32 %x, i32 10) 1563 %umin = call i32 @llvm.smin.i32(i32 %smin, i32 -20) 1564 ret i32 %umin 1565} 1566 1567define i32 @test_smin_umin4(i32 %x) { 1568; CHECK-LABEL: @test_smin_umin4( 1569; CHECK-NEXT: [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 -20) 1570; CHECK-NEXT: [[UMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[SMIN]], i32 10) 1571; CHECK-NEXT: ret i32 [[UMIN]] 1572; 1573 %smin = call i32 @llvm.umin.i32(i32 %x, i32 -20) 1574 %umin = call i32 @llvm.smin.i32(i32 %smin, i32 10) 1575 ret i32 %umin 1576} 1577 1578define i32 @test_umax_nonminmax(i32 %x) { 1579; CHECK-LABEL: @test_umax_nonminmax( 1580; CHECK-NEXT: [[Y:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]]) 1581; CHECK-NEXT: [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 1) 1582; CHECK-NEXT: ret i32 [[UMAX]] 1583; 1584 %y = call i32 @llvm.ctpop.i32(i32 %x) 1585 %umax = call i32 @llvm.umax.i32(i32 %y, i32 1) 1586 ret i32 %umax 1587} 1588 1589define <2 x i32> @test_umax_smax_vec_neg(<2 x i32> %x) { 1590; CHECK-LABEL: @test_umax_smax_vec_neg( 1591; CHECK-NEXT: [[SMAX:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 0, i32 -20>) 1592; CHECK-NEXT: [[UMAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SMAX]], <2 x i32> <i32 1, i32 10>) 1593; CHECK-NEXT: ret <2 x i32> [[UMAX]] 1594; 1595 %smax = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %x, <2 x i32> <i32 0, i32 -20>) 1596 %umax = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %smax, <2 x i32> <i32 1, i32 10>) 1597 ret <2 x i32> %umax 1598} 1599