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: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A:%.*]], i32 5) 21; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64 22; CHECK-NEXT: ret i64 [[TMP2]] 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: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A:%.*]], i32 5) 34; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 35; CHECK-NEXT: ret i64 [[TMP2]] 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: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A:%.*]], i32 5) 60; CHECK-NEXT: [[TMP2:%.*]] = zext i32 [[TMP1]] to i64 61; CHECK-NEXT: ret i64 [[TMP2]] 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 [[TMP2]], [[B]] 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: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 255) 134; CHECK-NEXT: [[TMP2:%.*]] = sitofp i32 [[TMP1]] to float 135; CHECK-NEXT: ret float [[TMP2]] 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: [[TMP1:%.*]] = call i64 @llvm.smax.i64(i64 [[X:%.*]], i64 255) 146; CHECK-NEXT: [[TMP2:%.*]] = sitofp i64 [[TMP1]] to float 147; CHECK-NEXT: ret float [[TMP2]] 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: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 11) 218; CHECK-NEXT: ret i32 [[TMP1]] 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: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 11, i32 11>) 230; CHECK-NEXT: ret <2 x i32> [[TMP1]] 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: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 24) 243; CHECK-NEXT: ret i32 [[TMP1]] 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: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 75) 256; CHECK-NEXT: ret i32 [[TMP1]] 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: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 68) 269; CHECK-NEXT: ret i32 [[TMP1]] 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: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 11) 282; CHECK-NEXT: ret i32 [[TMP1]] 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: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 11, i32 11>) 294; CHECK-NEXT: ret <2 x i32> [[TMP1]] 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: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 24) 307; CHECK-NEXT: ret i32 [[TMP1]] 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: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 36) 320; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 75) 321; CHECK-NEXT: ret i32 [[TMP2]] 322; 323 %cmp = icmp slt i32 %x, 36 324 %cond = select i1 %cmp, i32 36, i32 %x 325 %cmp3 = icmp slt i32 %cond, 75 326 %retval = select i1 %cmp3, i32 75, i32 %cond 327 ret i32 %retval 328} 329 330; MAX(MAX(X, 47), 68) -> MAX(X, 68) 331define i32 @test75(i32 %x) { 332; CHECK-LABEL: @test75( 333; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 68) 334; CHECK-NEXT: ret i32 [[TMP1]] 335; 336 %cmp = icmp ult i32 %x, 47 337 %cond = select i1 %cmp, i32 47, i32 %x 338 %cmp3 = icmp ult i32 %cond, 68 339 %retval = select i1 %cmp3, i32 68, i32 %cond 340 ret i32 %retval 341} 342 343; The next 10 tests are value clamping with constants: 344; https://llvm.org/bugs/show_bug.cgi?id=31693 345 346; (X <s C1) ? C1 : SMIN(X, C2) ==> SMAX(SMIN(X, C2), C1) 347 348define i32 @clamp_signed1(i32 %x) { 349; CHECK-LABEL: @clamp_signed1( 350; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) 351; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 15) 352; CHECK-NEXT: ret i32 [[TMP2]] 353; 354 %cmp2 = icmp slt i32 %x, 255 355 %min = select i1 %cmp2, i32 %x, i32 255 356 %cmp1 = icmp slt i32 %x, 15 357 %r = select i1 %cmp1, i32 15, i32 %min 358 ret i32 %r 359} 360 361; (X >s C1) ? C1 : SMAX(X, C2) ==> SMIN(SMAX(X, C2), C1) 362 363define i32 @clamp_signed2(i32 %x) { 364; CHECK-LABEL: @clamp_signed2( 365; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 15) 366; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 255) 367; CHECK-NEXT: ret i32 [[TMP2]] 368; 369 %cmp2 = icmp sgt i32 %x, 15 370 %max = select i1 %cmp2, i32 %x, i32 15 371 %cmp1 = icmp sgt i32 %x, 255 372 %r = select i1 %cmp1, i32 255, i32 %max 373 ret i32 %r 374} 375 376; (X >s C1) ? SMIN(X, C2) : C1 ==> SMAX(SMIN(X, C2), C1) 377 378define i32 @clamp_signed3(i32 %x) { 379; CHECK-LABEL: @clamp_signed3( 380; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 255) 381; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 15) 382; CHECK-NEXT: ret i32 [[TMP2]] 383; 384 %cmp2 = icmp slt i32 %x, 255 385 %min = select i1 %cmp2, i32 %x, i32 255 386 %cmp1 = icmp sgt i32 %x, 15 387 %r = select i1 %cmp1, i32 %min, i32 15 388 ret i32 %r 389} 390 391; (X <s C1) ? SMAX(X, C2) : C1 ==> SMIN(SMAX(X, C1), C2) 392 393define i32 @clamp_signed4(i32 %x) { 394; CHECK-LABEL: @clamp_signed4( 395; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 15) 396; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 255) 397; CHECK-NEXT: ret i32 [[TMP2]] 398; 399 %cmp2 = icmp sgt i32 %x, 15 400 %max = select i1 %cmp2, i32 %x, i32 15 401 %cmp1 = icmp slt i32 %x, 255 402 %r = select i1 %cmp1, i32 %max, i32 255 403 ret i32 %r 404} 405 406; (X <u C1) ? C1 : UMIN(X, C2) ==> UMAX(UMIN(X, C2), C1) 407 408define i32 @clamp_unsigned1(i32 %x) { 409; CHECK-LABEL: @clamp_unsigned1( 410; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255) 411; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 15) 412; CHECK-NEXT: ret i32 [[TMP2]] 413; 414 %cmp2 = icmp ult i32 %x, 255 415 %min = select i1 %cmp2, i32 %x, i32 255 416 %cmp1 = icmp ult i32 %x, 15 417 %r = select i1 %cmp1, i32 15, i32 %min 418 ret i32 %r 419} 420 421; (X >u C1) ? C1 : UMAX(X, C2) ==> UMIN(UMAX(X, C2), C1) 422 423define i32 @clamp_unsigned2(i32 %x) { 424; CHECK-LABEL: @clamp_unsigned2( 425; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 15) 426; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 255) 427; CHECK-NEXT: ret i32 [[TMP2]] 428; 429 %cmp2 = icmp ugt i32 %x, 15 430 %max = select i1 %cmp2, i32 %x, i32 15 431 %cmp1 = icmp ugt i32 %x, 255 432 %r = select i1 %cmp1, i32 255, i32 %max 433 ret i32 %r 434} 435 436; (X >u C1) ? UMIN(X, C2) : C1 ==> UMAX(UMIN(X, C2), C1) 437 438define i32 @clamp_unsigned3(i32 %x) { 439; CHECK-LABEL: @clamp_unsigned3( 440; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 255) 441; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 15) 442; CHECK-NEXT: ret i32 [[TMP2]] 443; 444 %cmp2 = icmp ult i32 %x, 255 445 %min = select i1 %cmp2, i32 %x, i32 255 446 %cmp1 = icmp ugt i32 %x, 15 447 %r = select i1 %cmp1, i32 %min, i32 15 448 ret i32 %r 449} 450 451; (X <u C1) ? UMAX(X, C2) : C1 ==> UMIN(UMAX(X, C2), C1) 452 453define i32 @clamp_unsigned4(i32 %x) { 454; CHECK-LABEL: @clamp_unsigned4( 455; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 15) 456; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 255) 457; CHECK-NEXT: ret i32 [[TMP2]] 458; 459 %cmp2 = icmp ugt i32 %x, 15 460 %max = select i1 %cmp2, i32 %x, i32 15 461 %cmp1 = icmp ult i32 %x, 255 462 %r = select i1 %cmp1, i32 %max, i32 255 463 ret i32 %r 464} 465 466; Check that clamp is recognized and there is no infinite 467; loop because of reverse cmp transformation: 468; (icmp sgt smin(PositiveA, B) 0) -> (icmp sgt B 0) 469define i32 @clamp_check_for_no_infinite_loop1(i32 %i) { 470; CHECK-LABEL: @clamp_check_for_no_infinite_loop1( 471; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[I:%.*]], i32 255) 472; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smax.i32(i32 [[TMP1]], i32 0) 473; CHECK-NEXT: ret i32 [[TMP2]] 474; 475 %cmp1 = icmp slt i32 %i, 255 476 %sel1 = select i1 %cmp1, i32 %i, i32 255 477 %cmp2 = icmp slt i32 %i, 0 478 %res = select i1 %cmp2, i32 0, i32 %sel1 479 ret i32 %res 480} 481; Check that there is no infinite loop in case of: 482; (icmp slt smax(NegativeA, B) 0) -> (icmp slt B 0) 483define i32 @clamp_check_for_no_infinite_loop2(i32 %i) { 484; CHECK-LABEL: @clamp_check_for_no_infinite_loop2( 485; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[I:%.*]], i32 -255) 486; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 0) 487; CHECK-NEXT: ret i32 [[TMP2]] 488; 489 %cmp1 = icmp sgt i32 %i, -255 490 %sel1 = select i1 %cmp1, i32 %i, i32 -255 491 %cmp2 = icmp slt i32 %i, 0 492 %res = select i1 %cmp2, i32 %sel1, i32 0 493 ret i32 %res 494} 495 496; Check that there is no infinite loop because of reverse cmp transformation: 497; (icmp slt smax(PositiveA, B) 2) -> (icmp eq B 1) 498define i32 @clamp_check_for_no_infinite_loop3(i32 %i) { 499; CHECK-LABEL: @clamp_check_for_no_infinite_loop3( 500; CHECK-NEXT: br i1 true, label [[TRUELABEL:%.*]], label [[FALSELABEL:%.*]] 501; CHECK: truelabel: 502; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[I:%.*]], i32 1) 503; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP1]], i32 2) 504; CHECK-NEXT: [[I7:%.*]] = shl nuw nsw i32 [[TMP2]], 2 505; CHECK-NEXT: ret i32 [[I7]] 506; CHECK: falselabel: 507; CHECK-NEXT: ret i32 0 508; 509 510 %i2 = icmp sgt i32 %i, 1 511 %i3 = select i1 %i2, i32 %i, i32 1 512 %i4 = icmp sgt i32 %i3, 0 513 br i1 %i4, label %truelabel, label %falselabel 514 515truelabel: ; %i<=1, %i3>0 516 %i5 = icmp slt i32 %i3, 2 517 %i6 = select i1 %i5, i32 %i3, i32 2 518 %i7 = shl nuw nsw i32 %i6, 2 519 ret i32 %i7 520 521falselabel: 522 ret i32 0 523} 524 525; The next 3 min tests should canonicalize to the same form...and not infinite loop. 526 527define double @PR31751_umin1(i32 %x) { 528; CHECK-LABEL: @PR31751_umin1( 529; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) 530; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP1]] to double 531; CHECK-NEXT: ret double [[CONV]] 532; 533 %cmp = icmp slt i32 %x, 0 534 %sel = select i1 %cmp, i32 2147483647, i32 %x 535 %conv = sitofp i32 %sel to double 536 ret double %conv 537} 538 539define double @PR31751_umin2(i32 %x) { 540; CHECK-LABEL: @PR31751_umin2( 541; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) 542; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP1]] to double 543; CHECK-NEXT: ret double [[CONV]] 544; 545 %cmp = icmp ult i32 %x, 2147483647 546 %sel = select i1 %cmp, i32 %x, i32 2147483647 547 %conv = sitofp i32 %sel to double 548 ret double %conv 549} 550 551define double @PR31751_umin3(i32 %x) { 552; CHECK-LABEL: @PR31751_umin3( 553; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 2147483647) 554; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP1]] to double 555; CHECK-NEXT: ret double [[CONV]] 556; 557 %cmp = icmp ugt i32 %x, 2147483647 558 %sel = select i1 %cmp, i32 2147483647, i32 %x 559 %conv = sitofp i32 %sel to double 560 ret double %conv 561} 562 563; The next 3 max tests should canonicalize to the same form...and not infinite loop. 564 565define double @PR31751_umax1(i32 %x) { 566; CHECK-LABEL: @PR31751_umax1( 567; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648) 568; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP1]] to double 569; CHECK-NEXT: ret double [[CONV]] 570; 571 %cmp = icmp sgt i32 %x, -1 572 %sel = select i1 %cmp, i32 2147483648, i32 %x 573 %conv = sitofp i32 %sel to double 574 ret double %conv 575} 576 577define double @PR31751_umax2(i32 %x) { 578; CHECK-LABEL: @PR31751_umax2( 579; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648) 580; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP1]] to double 581; CHECK-NEXT: ret double [[CONV]] 582; 583 %cmp = icmp ugt i32 %x, 2147483648 584 %sel = select i1 %cmp, i32 %x, i32 2147483648 585 %conv = sitofp i32 %sel to double 586 ret double %conv 587} 588 589define double @PR31751_umax3(i32 %x) { 590; CHECK-LABEL: @PR31751_umax3( 591; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 -2147483648) 592; CHECK-NEXT: [[CONV:%.*]] = sitofp i32 [[TMP1]] to double 593; CHECK-NEXT: ret double [[CONV]] 594; 595 %cmp = icmp ult i32 %x, 2147483648 596 %sel = select i1 %cmp, i32 2147483648, i32 %x 597 %conv = sitofp i32 %sel to double 598 ret double %conv 599} 600 601; The icmp/select form a canonical smax, so don't hide that by folding the final bitcast into the select. 602 603define float @bitcast_scalar_smax(float %x, float %y) { 604; CHECK-LABEL: @bitcast_scalar_smax( 605; CHECK-NEXT: [[BCX:%.*]] = bitcast float [[X:%.*]] to i32 606; CHECK-NEXT: [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32 607; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[BCX]], i32 [[BCY]]) 608; CHECK-NEXT: [[BCS:%.*]] = bitcast i32 [[TMP1]] to float 609; CHECK-NEXT: ret float [[BCS]] 610; 611 %bcx = bitcast float %x to i32 612 %bcy = bitcast float %y to i32 613 %cmp = icmp sgt i32 %bcx, %bcy 614 %sel = select i1 %cmp, i32 %bcx, i32 %bcy 615 %bcs = bitcast i32 %sel to float 616 ret float %bcs 617} 618 619; FIXME: Create a canonical umax by bitcasting the select. 620 621define float @bitcast_scalar_umax(float %x, float %y) { 622; CHECK-LABEL: @bitcast_scalar_umax( 623; CHECK-NEXT: [[BCX:%.*]] = bitcast float [[X:%.*]] to i32 624; CHECK-NEXT: [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32 625; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[BCX]], [[BCY]] 626; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], float [[X]], float [[Y]] 627; CHECK-NEXT: ret float [[SEL]] 628; 629 %bcx = bitcast float %x to i32 630 %bcy = bitcast float %y to i32 631 %cmp = icmp ugt i32 %bcx, %bcy 632 %sel = select i1 %cmp, float %x, float %y 633 ret float %sel 634} 635 636; PR32306 - https://bugs.llvm.org/show_bug.cgi?id=32306 637; The icmp/select form a canonical smin, so don't hide that by folding the final bitcast into the select. 638 639define <8 x float> @bitcast_vector_smin(<8 x float> %x, <8 x float> %y) { 640; CHECK-LABEL: @bitcast_vector_smin( 641; CHECK-NEXT: [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32> 642; CHECK-NEXT: [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32> 643; CHECK-NEXT: [[TMP1:%.*]] = call <8 x i32> @llvm.smin.v8i32(<8 x i32> [[BCX]], <8 x i32> [[BCY]]) 644; CHECK-NEXT: [[BCS:%.*]] = bitcast <8 x i32> [[TMP1]] to <8 x float> 645; CHECK-NEXT: ret <8 x float> [[BCS]] 646; 647 %bcx = bitcast <8 x float> %x to <8 x i32> 648 %bcy = bitcast <8 x float> %y to <8 x i32> 649 %cmp = icmp slt <8 x i32> %bcx, %bcy 650 %sel = select <8 x i1> %cmp, <8 x i32> %bcx, <8 x i32> %bcy 651 %bcs = bitcast <8 x i32> %sel to <8 x float> 652 ret <8 x float> %bcs 653} 654 655; FIXME: Create a canonical umin by bitcasting the select. 656 657define <8 x float> @bitcast_vector_umin(<8 x float> %x, <8 x float> %y) { 658; CHECK-LABEL: @bitcast_vector_umin( 659; CHECK-NEXT: [[BCX:%.*]] = bitcast <8 x float> [[X:%.*]] to <8 x i32> 660; CHECK-NEXT: [[BCY:%.*]] = bitcast <8 x float> [[Y:%.*]] to <8 x i32> 661; CHECK-NEXT: [[CMP:%.*]] = icmp slt <8 x i32> [[BCX]], [[BCY]] 662; CHECK-NEXT: [[SEL:%.*]] = select <8 x i1> [[CMP]], <8 x float> [[X]], <8 x float> [[Y]] 663; CHECK-NEXT: ret <8 x float> [[SEL]] 664; 665 %bcx = bitcast <8 x float> %x to <8 x i32> 666 %bcy = bitcast <8 x float> %y to <8 x i32> 667 %cmp = icmp slt <8 x i32> %bcx, %bcy 668 %sel = select <8 x i1> %cmp, <8 x float> %x, <8 x float> %y 669 ret <8 x float> %sel 670} 671 672; Check that we look through cast and recognize min idiom. 673 674define zeroext i8 @look_through_cast1(i32 %x) { 675; CHECK-LABEL: @look_through_cast1( 676; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 511) 677; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[TMP1]] to i8 678; CHECK-NEXT: ret i8 [[TMP2]] 679; 680 %cmp1 = icmp slt i32 %x, 511 681 %x_trunc = trunc i32 %x to i8 682 %res = select i1 %cmp1, i8 %x_trunc, i8 255 683 ret i8 %res 684} 685 686; Check that we look through cast but min is not recognized. 687 688define zeroext i8 @look_through_cast2(i32 %x) { 689; CHECK-LABEL: @look_through_cast2( 690; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[X:%.*]], 510 691; CHECK-NEXT: [[X_TRUNC:%.*]] = trunc i32 [[X]] to i8 692; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP1]], i8 [[X_TRUNC]], i8 -1 693; CHECK-NEXT: ret i8 [[RES]] 694; 695 %cmp1 = icmp slt i32 %x, 510 696 %x_trunc = trunc i32 %x to i8 697 %res = select i1 %cmp1, i8 %x_trunc, i8 255 698 ret i8 %res 699} 700 701define <2 x i8> @min_through_cast_vec1(<2 x i32> %x) { 702; CHECK-LABEL: @min_through_cast_vec1( 703; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 510, i32 511>) 704; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i8> 705; CHECK-NEXT: ret <2 x i8> [[TMP2]] 706; 707 %cmp = icmp slt <2 x i32> %x, <i32 510, i32 511> 708 %x_trunc = trunc <2 x i32> %x to <2 x i8> 709 %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 254, i8 255> 710 ret <2 x i8> %res 711} 712 713define <2 x i8> @min_through_cast_vec2(<2 x i32> %x) { 714; CHECK-LABEL: @min_through_cast_vec2( 715; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.smin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 511, i32 511>) 716; CHECK-NEXT: [[TMP2:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i8> 717; CHECK-NEXT: ret <2 x i8> [[TMP2]] 718; 719 %cmp = icmp slt <2 x i32> %x, <i32 511, i32 511> 720 %x_trunc = trunc <2 x i32> %x to <2 x i8> 721 %res = select <2 x i1> %cmp, <2 x i8> %x_trunc, <2 x i8> <i8 255, i8 255> 722 ret <2 x i8> %res 723} 724 725; Remove a min/max op in a sequence with a common operand. 726; PR35717: https://bugs.llvm.org/show_bug.cgi?id=35717 727 728; min(min(a, b), min(b, c)) --> min(min(a, b), c) 729 730define i32 @common_factor_smin(i32 %a, i32 %b, i32 %c) { 731; CHECK-LABEL: @common_factor_smin( 732; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[B:%.*]], i32 [[C:%.*]]) 733; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP1]], i32 [[A:%.*]]) 734; CHECK-NEXT: ret i32 [[TMP2]] 735; 736 %cmp_ab = icmp slt i32 %a, %b 737 %min_ab = select i1 %cmp_ab, i32 %a, i32 %b 738 %cmp_bc = icmp slt i32 %b, %c 739 %min_bc = select i1 %cmp_bc, i32 %b, i32 %c 740 %cmp_ab_bc = icmp slt i32 %min_ab, %min_bc 741 %min_abc = select i1 %cmp_ab_bc, i32 %min_ab, i32 %min_bc 742 ret i32 %min_abc 743} 744 745; max(max(a, b), max(c, b)) --> max(max(a, b), c) 746 747define <2 x i32> @common_factor_smax(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { 748; CHECK-LABEL: @common_factor_smax( 749; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[C:%.*]], <2 x i32> [[B:%.*]]) 750; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[TMP1]], <2 x i32> [[A:%.*]]) 751; CHECK-NEXT: ret <2 x i32> [[TMP2]] 752; 753 %cmp_ab = icmp sgt <2 x i32> %a, %b 754 %max_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b 755 %cmp_cb = icmp sgt <2 x i32> %c, %b 756 %max_cb = select <2 x i1> %cmp_cb, <2 x i32> %c, <2 x i32> %b 757 %cmp_ab_cb = icmp sgt <2 x i32> %max_ab, %max_cb 758 %max_abc = select <2 x i1> %cmp_ab_cb, <2 x i32> %max_ab, <2 x i32> %max_cb 759 ret <2 x i32> %max_abc 760} 761 762; min(min(b, c), min(a, b)) --> min(min(b, c), a) 763 764define <2 x i32> @common_factor_umin(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) { 765; CHECK-LABEL: @common_factor_umin( 766; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[A:%.*]], <2 x i32> [[B:%.*]]) 767; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[TMP1]], <2 x i32> [[C:%.*]]) 768; CHECK-NEXT: ret <2 x i32> [[TMP2]] 769; 770 %cmp_bc = icmp ult <2 x i32> %b, %c 771 %min_bc = select <2 x i1> %cmp_bc, <2 x i32> %b, <2 x i32> %c 772 %cmp_ab = icmp ult <2 x i32> %a, %b 773 %min_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b 774 %cmp_bc_ab = icmp ult <2 x i32> %min_bc, %min_ab 775 %min_abc = select <2 x i1> %cmp_bc_ab, <2 x i32> %min_bc, <2 x i32> %min_ab 776 ret <2 x i32> %min_abc 777} 778 779; max(max(b, c), max(b, a)) --> max(max(b, c), a) 780 781define i32 @common_factor_umax(i32 %a, i32 %b, i32 %c) { 782; CHECK-LABEL: @common_factor_umax( 783; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 784; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[C:%.*]]) 785; CHECK-NEXT: ret i32 [[TMP2]] 786; 787 %cmp_bc = icmp ugt i32 %b, %c 788 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 789 %cmp_ba = icmp ugt i32 %b, %a 790 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 791 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 792 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 793 ret i32 %max_abc 794} 795 796declare void @extra_use(i32) 797 798define i32 @common_factor_umax_extra_use_lhs(i32 %a, i32 %b, i32 %c) { 799; CHECK-LABEL: @common_factor_umax_extra_use_lhs( 800; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[C:%.*]]) 801; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[A:%.*]]) 802; CHECK-NEXT: call void @extra_use(i32 [[TMP1]]) 803; CHECK-NEXT: ret i32 [[TMP2]] 804; 805 %cmp_bc = icmp ugt i32 %b, %c 806 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 807 %cmp_ba = icmp ugt i32 %b, %a 808 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 809 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 810 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 811 call void @extra_use(i32 %max_bc) 812 ret i32 %max_abc 813} 814 815define i32 @common_factor_umax_extra_use_rhs(i32 %a, i32 %b, i32 %c) { 816; CHECK-LABEL: @common_factor_umax_extra_use_rhs( 817; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[A:%.*]]) 818; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[C:%.*]]) 819; CHECK-NEXT: call void @extra_use(i32 [[TMP1]]) 820; CHECK-NEXT: ret i32 [[TMP2]] 821; 822 %cmp_bc = icmp ugt i32 %b, %c 823 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 824 %cmp_ba = icmp ugt i32 %b, %a 825 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 826 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 827 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 828 call void @extra_use(i32 %max_ba) 829 ret i32 %max_abc 830} 831 832define i32 @common_factor_umax_extra_use_both(i32 %a, i32 %b, i32 %c) { 833; CHECK-LABEL: @common_factor_umax_extra_use_both( 834; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[B:%.*]], i32 [[C:%.*]]) 835; CHECK-NEXT: [[TMP2:%.*]] = call i32 @llvm.umax.i32(i32 [[B]], i32 [[A:%.*]]) 836; CHECK-NEXT: [[TMP3:%.*]] = call i32 @llvm.umax.i32(i32 [[TMP1]], i32 [[TMP2]]) 837; CHECK-NEXT: call void @extra_use(i32 [[TMP1]]) 838; CHECK-NEXT: call void @extra_use(i32 [[TMP2]]) 839; CHECK-NEXT: ret i32 [[TMP3]] 840; 841 %cmp_bc = icmp ugt i32 %b, %c 842 %max_bc = select i1 %cmp_bc, i32 %b, i32 %c 843 %cmp_ba = icmp ugt i32 %b, %a 844 %max_ba = select i1 %cmp_ba, i32 %b, i32 %a 845 %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba 846 %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba 847 call void @extra_use(i32 %max_bc) 848 call void @extra_use(i32 %max_ba) 849 ret i32 %max_abc 850} 851 852; This would assert. Don't assume that earlier min/max types match a possible later min/max. 853 854define float @not_min_of_min(i8 %i, float %x) { 855; CHECK-LABEL: @not_min_of_min( 856; CHECK-NEXT: [[CMP1_INV:%.*]] = fcmp fast oge float [[X:%.*]], 1.000000e+00 857; CHECK-NEXT: [[TMP1:%.*]] = select fast i1 [[CMP1_INV]], float 1.000000e+00, float [[X]] 858; CHECK-NEXT: [[CMP2_INV:%.*]] = fcmp fast oge float [[X]], 2.000000e+00 859; CHECK-NEXT: [[TMP2:%.*]] = select fast i1 [[CMP2_INV]], float 2.000000e+00, float [[X]] 860; CHECK-NEXT: [[CMP3:%.*]] = icmp ult i8 [[I:%.*]], 16 861; CHECK-NEXT: [[R:%.*]] = select i1 [[CMP3]], float [[TMP1]], float [[TMP2]] 862; CHECK-NEXT: ret float [[R]] 863; 864 %cmp1 = fcmp fast ult float %x, 1.0 865 %min1 = select i1 %cmp1, float %x, float 1.0 866 %cmp2 = fcmp fast ult float %x, 2.0 867 %min2 = select i1 %cmp2, float %x, float 2.0 868 %cmp3 = icmp ult i8 %i, 16 869 %r = select i1 %cmp3, float %min1, float %min2 870 ret float %r 871} 872 873define i32 @add_umin(i32 %x) { 874; CHECK-LABEL: @add_umin( 875; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 27) 876; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i32 [[TMP1]], 15 877; CHECK-NEXT: ret i32 [[TMP2]] 878; 879 %a = add nuw i32 %x, 15 880 %c = icmp ult i32 %a, 42 881 %r = select i1 %c, i32 %a, i32 42 882 ret i32 %r 883} 884 885define i32 @add_umin_constant_limit(i32 %x) { 886; CHECK-LABEL: @add_umin_constant_limit( 887; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[X:%.*]], 0 888; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[DOTNOT]], i32 41, i32 42 889; CHECK-NEXT: ret i32 [[TMP1]] 890; 891 %a = add nuw i32 %x, 41 892 %c = icmp ult i32 %a, 42 893 %r = select i1 %c, i32 %a, i32 42 894 ret i32 %r 895} 896 897; Negative test 898; TODO: assert that instsimplify always gets this? 899 900define i32 @add_umin_simplify(i32 %x) { 901; CHECK-LABEL: @add_umin_simplify( 902; CHECK-NEXT: ret i32 42 903; 904 %a = add nuw i32 %x, 42 905 %c = icmp ult i32 %a, 42 906 %r = select i1 %c, i32 %a, i32 42 907 ret i32 %r 908} 909 910; Negative test 911; TODO: assert that instsimplify always gets this? 912 913define i32 @add_umin_simplify2(i32 %x) { 914; CHECK-LABEL: @add_umin_simplify2( 915; CHECK-NEXT: ret i32 42 916; 917 %a = add nuw i32 %x, 43 918 %c = icmp ult i32 %a, 42 919 %r = select i1 %c, i32 %a, i32 42 920 ret i32 %r 921} 922 923; Negative test 924 925define i32 @add_umin_wrong_pred(i32 %x) { 926; CHECK-LABEL: @add_umin_wrong_pred( 927; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 928; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42) 929; CHECK-NEXT: ret i32 [[TMP1]] 930; 931 %a = add nuw i32 %x, 15 932 %c = icmp slt i32 %a, 42 933 %r = select i1 %c, i32 %a, i32 42 934 ret i32 %r 935} 936 937; Negative test 938 939define i32 @add_umin_wrong_wrap(i32 %x) { 940; CHECK-LABEL: @add_umin_wrong_wrap( 941; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 942; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42) 943; CHECK-NEXT: ret i32 [[TMP1]] 944; 945 %a = add nsw i32 %x, 15 946 %c = icmp ult i32 %a, 42 947 %r = select i1 %c, i32 %a, i32 42 948 ret i32 %r 949} 950 951; Negative test 952 953define i32 @add_umin_extra_use(i32 %x, i32* %p) { 954; CHECK-LABEL: @add_umin_extra_use( 955; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 956; CHECK-NEXT: store i32 [[A]], i32* [[P:%.*]], align 4 957; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42) 958; CHECK-NEXT: ret i32 [[TMP1]] 959; 960 %a = add nuw i32 %x, 15 961 store i32 %a, i32* %p 962 %c = icmp ult i32 %a, 42 963 %r = select i1 %c, i32 %a, i32 42 964 ret i32 %r 965} 966 967define <2 x i16> @add_umin_vec(<2 x i16> %x) { 968; CHECK-LABEL: @add_umin_vec( 969; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> <i16 225, i16 225>) 970; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw <2 x i16> [[TMP1]], <i16 15, i16 15> 971; CHECK-NEXT: ret <2 x i16> [[TMP2]] 972; 973 %a = add nuw <2 x i16> %x, <i16 15, i16 15> 974 %c = icmp ult <2 x i16> %a, <i16 240, i16 240> 975 %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240> 976 ret <2 x i16> %r 977} 978 979define i37 @add_umax(i37 %x) { 980; CHECK-LABEL: @add_umax( 981; CHECK-NEXT: [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 37) 982; CHECK-NEXT: [[TMP2:%.*]] = add nuw i37 [[TMP1]], 5 983; CHECK-NEXT: ret i37 [[TMP2]] 984; 985 %a = add nuw i37 %x, 5 986 %c = icmp ugt i37 %a, 42 987 %r = select i1 %c, i37 %a, i37 42 988 ret i37 %r 989} 990 991define i37 @add_umax_constant_limit(i37 %x) { 992; CHECK-LABEL: @add_umax_constant_limit( 993; CHECK-NEXT: [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 1) 994; CHECK-NEXT: [[TMP2:%.*]] = add nuw i37 [[TMP1]], 81 995; CHECK-NEXT: ret i37 [[TMP2]] 996; 997 %a = add nuw i37 %x, 81 998 %c = icmp ugt i37 %a, 82 999 %r = select i1 %c, i37 %a, i37 82 1000 ret i37 %r 1001} 1002 1003; Negative test 1004; TODO: assert that instsimplify always gets this? 1005 1006define i37 @add_umax_simplify(i37 %x) { 1007; CHECK-LABEL: @add_umax_simplify( 1008; CHECK-NEXT: [[A:%.*]] = add nuw i37 [[X:%.*]], 42 1009; CHECK-NEXT: ret i37 [[A]] 1010; 1011 %a = add nuw i37 %x, 42 1012 %c = icmp ugt i37 %a, 42 1013 %r = select i1 %c, i37 %a, i37 42 1014 ret i37 %r 1015} 1016 1017; Negative test 1018; TODO: assert that instsimplify always gets this? 1019 1020define i32 @add_umax_simplify2(i32 %x) { 1021; CHECK-LABEL: @add_umax_simplify2( 1022; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 57 1023; CHECK-NEXT: ret i32 [[A]] 1024; 1025 %a = add nuw i32 %x, 57 1026 %c = icmp ugt i32 %a, 56 1027 %r = select i1 %c, i32 %a, i32 56 1028 ret i32 %r 1029} 1030 1031; Negative test 1032 1033define i32 @add_umax_wrong_pred(i32 %x) { 1034; CHECK-LABEL: @add_umax_wrong_pred( 1035; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1036; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42) 1037; CHECK-NEXT: ret i32 [[TMP1]] 1038; 1039 %a = add nuw i32 %x, 15 1040 %c = icmp sgt i32 %a, 42 1041 %r = select i1 %c, i32 %a, i32 42 1042 ret i32 %r 1043} 1044 1045; Negative test 1046 1047; Without the nuw that would allow pushing the add through the umax, the 1048; add + icmp ugt combination can be interpreted as a range check, and would 1049; normally be canonicalized to use ult instead. However, this is not done when 1050; used as part of a umax to avoid breaking the SPF pattern. 1051define i32 @add_umax_wrong_wrap(i32 %x) { 1052; CHECK-LABEL: @add_umax_wrong_wrap( 1053; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1054; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42) 1055; CHECK-NEXT: ret i32 [[TMP1]] 1056; 1057 %a = add nsw i32 %x, 15 1058 %c = icmp ugt i32 %a, 42 1059 %r = select i1 %c, i32 %a, i32 42 1060 ret i32 %r 1061} 1062 1063; Negative test 1064 1065define i32 @add_umax_extra_use(i32 %x, i32* %p) { 1066; CHECK-LABEL: @add_umax_extra_use( 1067; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1068; CHECK-NEXT: store i32 [[A]], i32* [[P:%.*]], align 4 1069; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42) 1070; CHECK-NEXT: ret i32 [[TMP1]] 1071; 1072 %a = add nuw i32 %x, 15 1073 store i32 %a, i32* %p 1074 %c = icmp ugt i32 %a, 42 1075 %r = select i1 %c, i32 %a, i32 42 1076 ret i32 %r 1077} 1078 1079define <2 x i33> @add_umax_vec(<2 x i33> %x) { 1080; CHECK-LABEL: @add_umax_vec( 1081; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i33> @llvm.umax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> <i33 235, i33 235>) 1082; CHECK-NEXT: [[TMP2:%.*]] = add nuw <2 x i33> [[TMP1]], <i33 5, i33 5> 1083; CHECK-NEXT: ret <2 x i33> [[TMP2]] 1084; 1085 %a = add nuw <2 x i33> %x, <i33 5, i33 5> 1086 %c = icmp ugt <2 x i33> %a, <i33 240, i33 240> 1087 %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240> 1088 ret <2 x i33> %r 1089} 1090 1091define i8 @PR14613_umin(i8 %x) { 1092; CHECK-LABEL: @PR14613_umin( 1093; CHECK-NEXT: [[NARROW:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 15) 1094; CHECK-NEXT: ret i8 [[NARROW]] 1095; 1096 %u4 = zext i8 %x to i32 1097 %u5 = add nuw nsw i32 %u4, 15 1098 %u6 = icmp ult i32 %u5, 255 1099 %u7 = select i1 %u6, i32 %u5, i32 255 1100 %r = trunc i32 %u7 to i8 1101 ret i8 %r 1102} 1103 1104define i8 @PR14613_umax(i8 %x) { 1105; CHECK-LABEL: @PR14613_umax( 1106; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 -16) 1107; CHECK-NEXT: [[TMP2:%.*]] = add nsw i8 [[TMP1]], 15 1108; CHECK-NEXT: ret i8 [[TMP2]] 1109; 1110 %u4 = zext i8 %x to i32 1111 %u5 = add nuw nsw i32 %u4, 15 1112 %u6 = icmp ugt i32 %u5, 255 1113 %u7 = select i1 %u6, i32 %u5, i32 255 1114 %r = trunc i32 %u7 to i8 1115 ret i8 %r 1116} 1117 1118define i32 @add_smin(i32 %x) { 1119; CHECK-LABEL: @add_smin( 1120; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 27) 1121; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], 15 1122; CHECK-NEXT: ret i32 [[TMP2]] 1123; 1124 %a = add nsw i32 %x, 15 1125 %c = icmp slt i32 %a, 42 1126 %r = select i1 %c, i32 %a, i32 42 1127 ret i32 %r 1128} 1129 1130define i32 @add_smin_constant_limit(i32 %x) { 1131; CHECK-LABEL: @add_smin_constant_limit( 1132; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 2147483646) 1133; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[TMP1]], -3 1134; CHECK-NEXT: ret i32 [[TMP2]] 1135; 1136 %a = add nsw i32 %x, -3 1137 %c = icmp slt i32 %a, 2147483643 1138 %r = select i1 %c, i32 %a, i32 2147483643 1139 ret i32 %r 1140} 1141 1142; Negative test 1143; TODO: assert that instsimplify always gets this? 1144 1145define i32 @add_smin_simplify(i32 %x) { 1146; CHECK-LABEL: @add_smin_simplify( 1147; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], -3 1148; CHECK-NEXT: ret i32 [[A]] 1149; 1150 %a = add nsw i32 %x, -3 1151 %c = icmp slt i32 %a, 2147483644 1152 %r = select i1 %c, i32 %a, i32 2147483644 1153 ret i32 %r 1154} 1155 1156; Negative test 1157; TODO: assert that instsimplify always gets this? 1158 1159define i32 @add_smin_simplify2(i32 %x) { 1160; CHECK-LABEL: @add_smin_simplify2( 1161; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], -3 1162; CHECK-NEXT: ret i32 [[A]] 1163; 1164 %a = add nsw i32 %x, -3 1165 %c = icmp slt i32 %a, 2147483645 1166 %r = select i1 %c, i32 %a, i32 2147483645 1167 ret i32 %r 1168} 1169 1170; Negative test 1171 1172define i32 @add_smin_wrong_pred(i32 %x) { 1173; CHECK-LABEL: @add_smin_wrong_pred( 1174; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1175; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42) 1176; CHECK-NEXT: ret i32 [[TMP1]] 1177; 1178 %a = add nsw i32 %x, 15 1179 %c = icmp ult i32 %a, 42 1180 %r = select i1 %c, i32 %a, i32 42 1181 ret i32 %r 1182} 1183 1184; Negative test 1185 1186define i32 @add_smin_wrong_wrap(i32 %x) { 1187; CHECK-LABEL: @add_smin_wrong_wrap( 1188; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1189; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42) 1190; CHECK-NEXT: ret i32 [[TMP1]] 1191; 1192 %a = add nuw i32 %x, 15 1193 %c = icmp slt i32 %a, 42 1194 %r = select i1 %c, i32 %a, i32 42 1195 ret i32 %r 1196} 1197 1198; Negative test 1199 1200define i32 @add_smin_extra_use(i32 %x, i32* %p) { 1201; CHECK-LABEL: @add_smin_extra_use( 1202; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1203; CHECK-NEXT: store i32 [[A]], i32* [[P:%.*]], align 4 1204; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42) 1205; CHECK-NEXT: ret i32 [[TMP1]] 1206; 1207 %a = add nsw i32 %x, 15 1208 store i32 %a, i32* %p 1209 %c = icmp slt i32 %a, 42 1210 %r = select i1 %c, i32 %a, i32 42 1211 ret i32 %r 1212} 1213 1214define <2 x i16> @add_smin_vec(<2 x i16> %x) { 1215; CHECK-LABEL: @add_smin_vec( 1216; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> <i16 225, i16 225>) 1217; CHECK-NEXT: [[TMP2:%.*]] = add nsw <2 x i16> [[TMP1]], <i16 15, i16 15> 1218; CHECK-NEXT: ret <2 x i16> [[TMP2]] 1219; 1220 %a = add nsw <2 x i16> %x, <i16 15, i16 15> 1221 %c = icmp slt <2 x i16> %a, <i16 240, i16 240> 1222 %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240> 1223 ret <2 x i16> %r 1224} 1225 1226define i37 @add_smax(i37 %x) { 1227; CHECK-LABEL: @add_smax( 1228; CHECK-NEXT: [[TMP1:%.*]] = call i37 @llvm.smax.i37(i37 [[X:%.*]], i37 37) 1229; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw i37 [[TMP1]], 5 1230; CHECK-NEXT: ret i37 [[TMP2]] 1231; 1232 %a = add nsw i37 %x, 5 1233 %c = icmp sgt i37 %a, 42 1234 %r = select i1 %c, i37 %a, i37 42 1235 ret i37 %r 1236} 1237 1238define i8 @add_smax_constant_limit(i8 %x) { 1239; CHECK-LABEL: @add_smax_constant_limit( 1240; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127) 1241; CHECK-NEXT: [[TMP2:%.*]] = add nsw i8 [[TMP1]], 125 1242; CHECK-NEXT: ret i8 [[TMP2]] 1243; 1244 %a = add nsw i8 %x, 125 1245 %c = icmp sgt i8 %a, -2 1246 %r = select i1 %c, i8 %a, i8 -2 1247 ret i8 %r 1248} 1249 1250; Negative test 1251; TODO: assert that instsimplify always gets this? 1252 1253define i8 @add_smax_simplify(i8 %x) { 1254; CHECK-LABEL: @add_smax_simplify( 1255; CHECK-NEXT: [[A:%.*]] = add nsw i8 [[X:%.*]], 126 1256; CHECK-NEXT: ret i8 [[A]] 1257; 1258 %a = add nsw i8 %x, 126 1259 %c = icmp sgt i8 %a, -2 1260 %r = select i1 %c, i8 %a, i8 -2 1261 ret i8 %r 1262} 1263 1264; Negative test 1265; TODO: assert that instsimplify always gets this? 1266 1267define i8 @add_smax_simplify2(i8 %x) { 1268; CHECK-LABEL: @add_smax_simplify2( 1269; CHECK-NEXT: [[A:%.*]] = add nsw i8 [[X:%.*]], 127 1270; CHECK-NEXT: ret i8 [[A]] 1271; 1272 %a = add nsw i8 %x, 127 1273 %c = icmp sgt i8 %a, -2 1274 %r = select i1 %c, i8 %a, i8 -2 1275 ret i8 %r 1276} 1277 1278; Negative test 1279 1280define i32 @add_smax_wrong_pred(i32 %x) { 1281; CHECK-LABEL: @add_smax_wrong_pred( 1282; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1283; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42) 1284; CHECK-NEXT: ret i32 [[TMP1]] 1285; 1286 %a = add nsw i32 %x, 15 1287 %c = icmp ugt i32 %a, 42 1288 %r = select i1 %c, i32 %a, i32 42 1289 ret i32 %r 1290} 1291 1292; Negative test 1293 1294define i32 @add_smax_wrong_wrap(i32 %x) { 1295; CHECK-LABEL: @add_smax_wrong_wrap( 1296; CHECK-NEXT: [[A:%.*]] = add nuw i32 [[X:%.*]], 15 1297; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42) 1298; CHECK-NEXT: ret i32 [[TMP1]] 1299; 1300 %a = add nuw i32 %x, 15 1301 %c = icmp sgt i32 %a, 42 1302 %r = select i1 %c, i32 %a, i32 42 1303 ret i32 %r 1304} 1305 1306; Negative test 1307 1308define i32 @add_smax_extra_use(i32 %x, i32* %p) { 1309; CHECK-LABEL: @add_smax_extra_use( 1310; CHECK-NEXT: [[A:%.*]] = add nsw i32 [[X:%.*]], 15 1311; CHECK-NEXT: store i32 [[A]], i32* [[P:%.*]], align 4 1312; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42) 1313; CHECK-NEXT: ret i32 [[TMP1]] 1314; 1315 %a = add nsw i32 %x, 15 1316 store i32 %a, i32* %p 1317 %c = icmp sgt i32 %a, 42 1318 %r = select i1 %c, i32 %a, i32 42 1319 ret i32 %r 1320} 1321 1322define <2 x i33> @add_smax_vec(<2 x i33> %x) { 1323; CHECK-LABEL: @add_smax_vec( 1324; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i33> @llvm.smax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> <i33 235, i33 235>) 1325; CHECK-NEXT: [[TMP2:%.*]] = add nuw nsw <2 x i33> [[TMP1]], <i33 5, i33 5> 1326; CHECK-NEXT: ret <2 x i33> [[TMP2]] 1327; 1328 %a = add nsw <2 x i33> %x, <i33 5, i33 5> 1329 %c = icmp sgt <2 x i33> %a, <i33 240, i33 240> 1330 %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240> 1331 ret <2 x i33> %r 1332} 1333 1334define i8 @PR14613_smin(i8 %x) { 1335; CHECK-LABEL: @PR14613_smin( 1336; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 40) 1337; CHECK-NEXT: [[NARROW:%.*]] = add nsw i8 [[TMP1]], 15 1338; CHECK-NEXT: ret i8 [[NARROW]] 1339; 1340 %u4 = sext i8 %x to i32 1341 %u5 = add nuw nsw i32 %u4, 15 1342 %u6 = icmp slt i32 %u5, 55 1343 %u7 = select i1 %u6, i32 %u5, i32 55 1344 %r = trunc i32 %u7 to i8 1345 ret i8 %r 1346} 1347 1348define i8 @PR14613_smax(i8 %x) { 1349; CHECK-LABEL: @PR14613_smax( 1350; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 40) 1351; CHECK-NEXT: [[NARROW:%.*]] = add nuw i8 [[TMP1]], 15 1352; CHECK-NEXT: ret i8 [[NARROW]] 1353; 1354 %u4 = sext i8 %x to i32 1355 %u5 = add nuw nsw i32 %u4, 15 1356 %u6 = icmp sgt i32 %u5, 55 1357 %u7 = select i1 %u6, i32 %u5, i32 55 1358 %r = trunc i32 %u7 to i8 1359 ret i8 %r 1360} 1361 1362define i8 @PR46271(<2 x i8> %x) { 1363; CHECK-LABEL: @PR46271( 1364; CHECK-NEXT: [[A:%.*]] = icmp sgt <2 x i8> [[X:%.*]], <i8 -1, i8 -1> 1365; CHECK-NEXT: [[B:%.*]] = select <2 x i1> [[A]], <2 x i8> [[X]], <2 x i8> <i8 poison, i8 -1> 1366; CHECK-NEXT: [[TMP1:%.*]] = extractelement <2 x i8> [[B]], i64 1 1367; CHECK-NEXT: [[R:%.*]] = xor i8 [[TMP1]], -1 1368; CHECK-NEXT: ret i8 [[R]] 1369; 1370 %a = icmp sgt <2 x i8> %x, <i8 -1, i8 -1> 1371 %b = select <2 x i1> %a, <2 x i8> %x, <2 x i8> <i8 undef, i8 -1> 1372 %not = xor <2 x i8> %b, <i8 undef, i8 -1> 1373 %r = extractelement <2 x i8> %not, i32 1 1374 ret i8 %r 1375} 1376 1377define i32 @twoway_clamp_lt(i32 %num) { 1378; CHECK-LABEL: @twoway_clamp_lt( 1379; CHECK-NEXT: entry: 1380; CHECK-NEXT: [[TMP0:%.*]] = icmp sgt i32 [[NUM:%.*]], 13767 1381; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[TMP0]], i32 13768, i32 13767 1382; CHECK-NEXT: ret i32 [[TMP1]] 1383; 1384entry: 1385 %cmp1 = icmp slt i32 %num, 13768 1386 %s1 = select i1 %cmp1, i32 %num, i32 13768 1387 %cmp2 = icmp sgt i32 %s1, 13767 1388 %r = select i1 %cmp2, i32 %s1, i32 13767 1389 ret i32 %r 1390} 1391 1392define i32 @twoway_clamp_gt(i32 %num) { 1393; CHECK-LABEL: @twoway_clamp_gt( 1394; CHECK-NEXT: entry: 1395; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 13767) 1396; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[TMP0]], i32 13768) 1397; CHECK-NEXT: ret i32 [[TMP1]] 1398; 1399entry: 1400 %cmp1 = icmp sgt i32 %num, 13767 1401 %s1 = select i1 %cmp1, i32 %num, i32 13767 1402 %cmp2 = icmp slt i32 %s1, 13768 1403 %r = select i1 %cmp2, i32 %s1, i32 13768 1404 ret i32 %r 1405} 1406 1407define i32 @twoway_clamp_gt_nonconst(i32 %num, i32 %k) { 1408; CHECK-LABEL: @twoway_clamp_gt_nonconst( 1409; CHECK-NEXT: entry: 1410; CHECK-NEXT: [[K1:%.*]] = add i32 [[K:%.*]], 1 1411; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 [[K]]) 1412; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[TMP0]], i32 [[K1]]) 1413; CHECK-NEXT: ret i32 [[TMP1]] 1414; 1415entry: 1416 %k1 = add i32 %k, 1 1417 %cmp1 = icmp sgt i32 %num, %k 1418 %s1 = select i1 %cmp1, i32 %num, i32 %k 1419 %cmp2 = icmp slt i32 %s1, %k1 1420 %r = select i1 %cmp2, i32 %s1, i32 %k1 1421 ret i32 %r 1422} 1423