brintos

brintos / llvm-project-archived public Read only

0
0
Text · 60.1 KiB · a982225 Raw
1845 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 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 i649; CHECK-NEXT:    ret i64 [[TMP2]]10;11  %1 = icmp slt i32 %a, 512  %2 = select i1 %1, i32 %a, i32 513  %3 = sext i32 %2 to i6414  ret i64 %315}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 i6422; CHECK-NEXT:    ret i64 [[TMP1]]23;24  %1 = icmp slt i32 %a, 525  %2 = sext i32 %a to i6426  %3 = select i1 %1, i64 %2, i64 527  ret i64 %328}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 i6435; CHECK-NEXT:    ret i64 [[TMP1]]36;37  %1 = icmp ult i32 %a, 538  %2 = zext i32 %a to i6439  %3 = select i1 %1, i64 5, i64 %240  ret i64 %341}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 i3248; CHECK-NEXT:    ret i32 [[TMP2]]49;50  %1 = icmp slt i64 %a, 551  %2 = trunc i64 %a to i3252  %3 = select i1 %1, i32 %2, i32 553  ret i32 %354}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 i6461; CHECK-NEXT:    ret i64 [[TMP1]]62;63  %1 = icmp slt i32 %a, 564  %2 = zext i32 %a to i6465  %3 = select i1 %1, i64 5, i64 %266  ret i64 %367}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 float73; CHECK-NEXT:    ret float [[TMP2]]74;75  %1 = icmp slt i32 %a, 076  %2 = select i1 %1, i32 %a, i32 077  %3 = sitofp i32 %2 to float78  ret float %379}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 i1685; CHECK-NEXT:    ret i16 [[TMP2]]86;87  %1 = icmp slt i32 %a, -3276888  %2 = trunc i32 %a to i1689  %3 = select i1 %1, i16 %2, i16 -3276890  ret i16 %391}92 93; Just check for no infinite loop. InstSimplify liked to94; "simplify" -32767 by removing all the sign bits,95; which led to a canonicalization fight between different96; 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 i32101; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i32 [[B:%.*]], 42102; 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 i32105; CHECK-NEXT:    ret i32 [[TMP6]]106;107  %1 = icmp slt i64 %a, -32767108  %2 = select i1 %1, i64 %a, i64 -32767109  %3 = trunc i64 %2 to i32110  %4 = icmp slt i32 %b, 42111  %5 = select i1 %4, i32 42, i32 %3112  %6 = icmp ne i32 %5, %b113  %7 = zext i1 %6 to i32114  ret i32 %7115}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:%.*]], -1121; CHECK-NEXT:    [[TMP2:%.*]] = sext i32 [[A]] to i64122; CHECK-NEXT:    [[TMP3:%.*]] = select i1 [[TMP1]], i64 [[TMP2]], i64 4294967295123; CHECK-NEXT:    ret i64 [[TMP3]]124;125  %1 = icmp sgt i32 %a, -1126  %2 = sext i32 %a to i64127  %3 = select i1 %1, i64 %2, i64 4294967295128  ret i64 %3129}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 float135; CHECK-NEXT:    ret float [[R]]136;137  %f_x = sitofp i32 %x to float138  %cmp = icmp sgt i32 %x, 255139  %r = select i1 %cmp, float %f_x, float 255.0140  ret float %r141}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 float147; CHECK-NEXT:    ret float [[R]]148;149  %f_x = sitofp i64 %x to float150  %cmp = icmp sgt i64 %x, 255151  %r = select i1 %cmp, float %f_x, float 255.0152  ret float %r153}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, %t0169  %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> %t4172  ret <4 x i32> %t5173}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, %t1189  %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> %t4192  ret <4 x i32> %t5193}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, %t0208  %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> %t4211  ret <4 x float> %t5212}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, %x221  %cond = select i1 %cmp, i32 11, i32 %x222  %cmp3 = icmp slt i32 92, %cond223  %retval = select i1 %cmp3, i32 92, i32 %cond224  ret i32 %retval225}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>, %x233  %cond = select <2 x i1> %cmp, <2 x i32> <i32 11, i32 11>, <2 x i32> %x234  %cmp3 = icmp slt <2 x i32> <i32 92, i32 92>, %cond235  %retval = select <2 x i1> %cmp3, <2 x i32> <i32 92, i32 92>, <2 x i32> %cond236  ret <2 x i32> %retval237}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, %x246  %cond = select i1 %cmp, i32 24, i32 %x247  %cmp3 = icmp ult i32 83, %cond248  %retval = select i1 %cmp3, i32 83, i32 %cond249  ret i32 %retval250}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, 75259  %cond = select i1 %cmp, i32 75, i32 %x260  %cmp3 = icmp slt i32 %cond, 36261  %retval = select i1 %cmp3, i32 36, i32 %cond262  ret i32 %retval263}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, 68272  %cond = select i1 %cmp, i32 68, i32 %x273  %cmp3 = icmp ult i32 %cond, 47274  %retval = select i1 %cmp3, i32 47, i32 %cond275  ret i32 %retval276}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, 92285  %cond = select i1 %cmp, i32 92, i32 %x286  %cmp3 = icmp sgt i32 %cond, 11287  %retval = select i1 %cmp3, i32 11, i32 %cond288  ret i32 %retval289}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> %x298  %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> %cond300  ret <2 x i32> %retval301}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, 83310  %cond = select i1 %cmp, i32 83, i32 %x311  %cmp3 = icmp ugt i32 %cond, 24312  %retval = select i1 %cmp3, i32 24, i32 %cond313  ret i32 %retval314}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, 36323  %cond = select i1 %cmp, i32 36, i32 %x324  %cmp3 = icmp slt i32 %cond, 75325  %retval = select i1 %cmp3, i32 75, i32 %cond326  ret i32 %retval327}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, 47336  %cond = select i1 %cmp, i32 47, i32 %x337  %cmp3 = icmp ult i32 %cond, 68338  %retval = select i1 %cmp3, i32 68, i32 %cond339  ret i32 %retval340}341 342; The next 10 tests are value clamping with constants:343; https://llvm.org/bugs/show_bug.cgi?id=31693344 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:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN:%.*]], i32 15)350; CHECK-NEXT:    [[R1:%.*]] = call i32 @llvm.smin.i32(i32 [[R]], i32 255)351; CHECK-NEXT:    ret i32 [[R1]]352;353  %cmp2 = icmp slt i32 %x, 255354  %min = select i1 %cmp2, i32 %x, i32 255355  %cmp1 = icmp slt i32 %x, 15356  %r = select i1 %cmp1, i32 15, i32 %min357  ret i32 %r358}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, 15369  %max = select i1 %cmp2, i32 %x, i32 15370  %cmp1 = icmp sgt i32 %x, 255371  %r = select i1 %cmp1, i32 255, i32 %max372  ret i32 %r373}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:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[MIN:%.*]], i32 15)380; CHECK-NEXT:    [[R1:%.*]] = call i32 @llvm.smin.i32(i32 [[R]], i32 255)381; CHECK-NEXT:    ret i32 [[R1]]382;383  %cmp2 = icmp slt i32 %x, 255384  %min = select i1 %cmp2, i32 %x, i32 255385  %cmp1 = icmp sgt i32 %x, 15386  %r = select i1 %cmp1, i32 %min, i32 15387  ret i32 %r388}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, 15399  %max = select i1 %cmp2, i32 %x, i32 15400  %cmp1 = icmp slt i32 %x, 255401  %r = select i1 %cmp1, i32 %max, i32 255402  ret i32 %r403}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:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN:%.*]], i32 15)410; CHECK-NEXT:    [[R1:%.*]] = call i32 @llvm.umin.i32(i32 [[R]], i32 255)411; CHECK-NEXT:    ret i32 [[R1]]412;413  %cmp2 = icmp ult i32 %x, 255414  %min = select i1 %cmp2, i32 %x, i32 255415  %cmp1 = icmp ult i32 %x, 15416  %r = select i1 %cmp1, i32 15, i32 %min417  ret i32 %r418}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, 15429  %max = select i1 %cmp2, i32 %x, i32 15430  %cmp1 = icmp ugt i32 %x, 255431  %r = select i1 %cmp1, i32 255, i32 %max432  ret i32 %r433}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:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[MIN:%.*]], i32 15)440; CHECK-NEXT:    [[R1:%.*]] = call i32 @llvm.umin.i32(i32 [[R]], i32 255)441; CHECK-NEXT:    ret i32 [[R1]]442;443  %cmp2 = icmp ult i32 %x, 255444  %min = select i1 %cmp2, i32 %x, i32 255445  %cmp1 = icmp ugt i32 %x, 15446  %r = select i1 %cmp1, i32 %min, i32 15447  ret i32 %r448}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, 15459  %max = select i1 %cmp2, i32 %x, i32 15460  %cmp1 = icmp ult i32 %x, 255461  %r = select i1 %cmp1, i32 %max, i32 255462  ret i32 %r463}464 465; Check that clamp is recognized and there is no infinite466; 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:    [[RES:%.*]] = call i32 @llvm.smax.i32(i32 [[SEL1:%.*]], i32 0)471; CHECK-NEXT:    [[RES1:%.*]] = call i32 @llvm.smin.i32(i32 [[RES]], i32 255)472; CHECK-NEXT:    ret i32 [[RES1]]473;474  %cmp1 = icmp slt i32 %i, 255475  %sel1 = select i1 %cmp1, i32 %i, i32 255476  %cmp2 = icmp slt i32 %i, 0477  %res = select i1 %cmp2, i32 0, i32 %sel1478  ret i32 %res479}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, -255489  %sel1 = select i1 %cmp1, i32 %i, i32 -255490  %cmp2 = icmp slt i32 %i, 0491  %res = select i1 %cmp2, i32 %sel1, i32 0492  ret i32 %res493}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]], 2504; CHECK-NEXT:    ret i32 [[I7]]505; CHECK:       falselabel:506; CHECK-NEXT:    ret i32 0507;508 509  %i2 = icmp sgt i32 %i, 1510  %i3 = select i1 %i2, i32 %i, i32 1511  %i4 = icmp sgt i32 %i3, 0512  br i1 %i4, label %truelabel, label %falselabel513 514truelabel: ; %i<=1, %i3>0515  %i5 = icmp slt i32 %i3, 2516  %i6 = select i1 %i5, i32 %i3, i32 2517  %i7 = shl nuw nsw i32 %i6, 2518  ret i32 %i7519 520falselabel:521  ret i32 0522}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 double530; CHECK-NEXT:    ret double [[CONV]]531;532  %cmp = icmp slt i32 %x, 0533  %sel = select i1 %cmp, i32 2147483647, i32 %x534  %conv = sitofp i32 %sel to double535  ret double %conv536}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 double542; CHECK-NEXT:    ret double [[CONV]]543;544  %cmp = icmp ult i32 %x, 2147483647545  %sel = select i1 %cmp, i32 %x, i32 2147483647546  %conv = sitofp i32 %sel to double547  ret double %conv548}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 double554; CHECK-NEXT:    ret double [[CONV]]555;556  %cmp = icmp ugt i32 %x, 2147483647557  %sel = select i1 %cmp, i32 2147483647, i32 %x558  %conv = sitofp i32 %sel to double559  ret double %conv560}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 double568; CHECK-NEXT:    ret double [[CONV]]569;570  %cmp = icmp sgt i32 %x, -1571  %sel = select i1 %cmp, i32 2147483648, i32 %x572  %conv = sitofp i32 %sel to double573  ret double %conv574}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 double580; CHECK-NEXT:    ret double [[CONV]]581;582  %cmp = icmp ugt i32 %x, 2147483648583  %sel = select i1 %cmp, i32 %x, i32 2147483648584  %conv = sitofp i32 %sel to double585  ret double %conv586}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 double592; CHECK-NEXT:    ret double [[CONV]]593;594  %cmp = icmp ult i32 %x, 2147483648595  %sel = select i1 %cmp, i32 2147483648, i32 %x596  %conv = sitofp i32 %sel to double597  ret double %conv598}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 i32605; CHECK-NEXT:    [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32606; CHECK-NEXT:    [[SEL:%.*]] = call i32 @llvm.smax.i32(i32 [[BCX]], i32 [[BCY]])607; CHECK-NEXT:    [[BCS:%.*]] = bitcast i32 [[SEL]] to float608; CHECK-NEXT:    ret float [[BCS]]609;610  %bcx = bitcast float %x to i32611  %bcy = bitcast float %y to i32612  %cmp = icmp sgt i32 %bcx, %bcy613  %sel = select i1 %cmp, i32 %bcx, i32 %bcy614  %bcs = bitcast i32 %sel to float615  ret float %bcs616}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 i32623; CHECK-NEXT:    [[BCY:%.*]] = bitcast float [[Y:%.*]] to i32624; 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 i32629  %bcy = bitcast float %y to i32630  %cmp = icmp ugt i32 %bcx, %bcy631  %sel = select i1 %cmp, float %x, float %y632  ret float %sel633}634 635; PR32306 - https://bugs.llvm.org/show_bug.cgi?id=32306636; 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, %bcy649  %sel = select <8 x i1> %cmp, <8 x i32> %bcx, <8 x i32> %bcy650  %bcs = bitcast <8 x i32> %sel to <8 x float>651  ret <8 x float> %bcs652}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, %bcy667  %sel = select <8 x i1> %cmp, <8 x float> %x, <8 x float> %y668  ret <8 x float> %sel669}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 i8677; CHECK-NEXT:    ret i8 [[RES]]678;679  %cmp1 = icmp slt i32 %x, 511680  %x_trunc = trunc i32 %x to i8681  %res = select i1 %cmp1, i8 %x_trunc, i8 255682  ret i8 %res683}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:%.*]], 510690; CHECK-NEXT:    [[X_TRUNC:%.*]] = trunc i32 [[X]] to i8691; CHECK-NEXT:    [[RES:%.*]] = select i1 [[CMP1]], i8 [[X_TRUNC]], i8 -1692; CHECK-NEXT:    ret i8 [[RES]]693;694  %cmp1 = icmp slt i32 %x, 510695  %x_trunc = trunc i32 %x to i8696  %res = select i1 %cmp1, i8 %x_trunc, i8 255697  ret i8 %res698}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 i32703; CHECK-NEXT:    [[SEL1:%.*]] = call i32 @llvm.smin.i32(i32 [[MIN:%.*]], i32 [[A32]])704; CHECK-NEXT:    [[SEL:%.*]] = trunc i32 [[SEL1]] to i8705; CHECK-NEXT:    ret i8 [[SEL]]706;707  %a32 = sext i8 %a to i32708  %cmp = icmp slt i32 %a32, %min709  %min8 = trunc i32 %min to i8710  %sel = select i1 %cmp, i8 %a, i8 %min8711  ret i8 %sel712}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 i32717; CHECK-NEXT:    [[SEL1:%.*]] = call i32 @llvm.smax.i32(i32 [[MAX:%.*]], i32 [[A32]])718; CHECK-NEXT:    [[SEL:%.*]] = trunc i32 [[SEL1]] to i16719; CHECK-NEXT:    ret i16 [[SEL]]720;721  %a32 = zext i16 %a to i32722  %cmp = icmp sgt i32 %max, %a32723  %max8 = trunc i32 %max to i16724  %sel = select i1 %cmp, i16 %max8, i16 %a725  ret i16 %sel726}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> %res738}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> %res750}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, %min761  %min8 = trunc <8 x i32> %min to <8 x i8>762  %sel = select <8 x i1> %cmp, <8 x i8> %a, <8 x i8> %min8763  ret <8 x i8> %sel764}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, %max775  %max8 = trunc <8 x i64> %max to <8 x i32>776  %sel = select <8 x i1> %cmp, <8 x i32> %a, <8 x i32> %max8777  ret <8 x i32> %sel778}779 780; Remove a min/max op in a sequence with a common operand.781; PR35717: https://bugs.llvm.org/show_bug.cgi?id=35717782 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, %b792  %min_ab = select i1 %cmp_ab, i32 %a, i32 %b793  %cmp_bc = icmp slt i32 %b, %c794  %min_bc = select i1 %cmp_bc, i32 %b, i32 %c795  %cmp_ab_bc = icmp slt i32 %min_ab, %min_bc796  %min_abc = select i1 %cmp_ab_bc, i32 %min_ab, i32 %min_bc797  ret i32 %min_abc798}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, %b809  %max_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b810  %cmp_cb = icmp sgt <2 x i32> %c, %b811  %max_cb = select <2 x i1> %cmp_cb, <2 x i32> %c, <2 x i32> %b812  %cmp_ab_cb = icmp sgt <2 x i32> %max_ab, %max_cb813  %max_abc = select <2 x i1> %cmp_ab_cb, <2 x i32> %max_ab, <2 x i32> %max_cb814  ret <2 x i32> %max_abc815}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, %c826  %min_bc = select <2 x i1> %cmp_bc, <2 x i32> %b, <2 x i32> %c827  %cmp_ab = icmp ult <2 x i32> %a, %b828  %min_ab = select <2 x i1> %cmp_ab, <2 x i32> %a, <2 x i32> %b829  %cmp_bc_ab = icmp ult <2 x i32> %min_bc, %min_ab830  %min_abc = select <2 x i1> %cmp_bc_ab, <2 x i32> %min_bc, <2 x i32> %min_ab831  ret <2 x i32> %min_abc832}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, %c843  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c844  %cmp_ba = icmp ugt i32 %b, %a845  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a846  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba847  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba848  ret i32 %max_abc849}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, %c861  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c862  %cmp_ba = icmp ugt i32 %b, %a863  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a864  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba865  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba866  call void @extra_use(i32 %max_bc)867  ret i32 %max_abc868}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, %c878  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c879  %cmp_ba = icmp ugt i32 %b, %a880  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a881  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba882  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba883  call void @extra_use(i32 %max_ba)884  ret i32 %max_abc885}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, %c897  %max_bc = select i1 %cmp_bc, i32 %b, i32 %c898  %cmp_ba = icmp ugt i32 %b, %a899  %max_ba = select i1 %cmp_ba, i32 %b, i32 %a900  %cmp_bc_ba = icmp ugt i32 %max_bc, %max_ba901  %max_abc = select i1 %cmp_bc_ba, i32 %max_bc, i32 %max_ba902  call void @extra_use(i32 %max_bc)903  call void @extra_use(i32 %max_ba)904  ret i32 %max_abc905}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:    [[CMP1_INV:%.*]] = fcmp fast oge float [[X:%.*]], 1.000000e+00912; CHECK-NEXT:    [[MIN1:%.*]] = select nnan ninf i1 [[CMP1_INV]], float 1.000000e+00, float [[X]]913; CHECK-NEXT:    [[CMP2_INV:%.*]] = fcmp fast oge float [[X]], 2.000000e+00914; CHECK-NEXT:    [[MIN2:%.*]] = select nnan ninf i1 [[CMP2_INV]], float 2.000000e+00, float [[X]]915; CHECK-NEXT:    [[CMP3:%.*]] = icmp ult i8 [[I:%.*]], 16916; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP3]], float [[MIN1]], float [[MIN2]]917; CHECK-NEXT:    ret float [[R]]918;919  %cmp1 = fcmp fast ult float %x, 1.0920  %min1 = select i1 %cmp1, float %x, float 1.0921  %cmp2 = fcmp fast ult float %x, 2.0922  %min2 = select i1 %cmp2, float %x, float 2.0923  %cmp3 = icmp ult i8 %i, 16924  %r = select i1 %cmp3, float %min1, float %min2925  ret float %r926}927 928define i32 @add_umin(i32 %x) {929; CHECK-LABEL: @add_umin(930; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 27)931; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i32 [[TMP1]], 15932; CHECK-NEXT:    ret i32 [[R]]933;934  %a = add nuw i32 %x, 15935  %c = icmp ult i32 %a, 42936  %r = select i1 %c, i32 %a, i32 42937  ret i32 %r938}939 940define i32 @add_umin_constant_limit(i32 %x) {941; CHECK-LABEL: @add_umin_constant_limit(942; CHECK-NEXT:    [[DOTNOT:%.*]] = icmp eq i32 [[X:%.*]], 0943; CHECK-NEXT:    [[R:%.*]] = select i1 [[DOTNOT]], i32 41, i32 42944; CHECK-NEXT:    ret i32 [[R]]945;946  %a = add nuw i32 %x, 41947  %c = icmp ult i32 %a, 42948  %r = select i1 %c, i32 %a, i32 42949  ret i32 %r950}951 952; Negative test953; TODO: assert that instsimplify always gets this?954 955define i32 @add_umin_simplify(i32 %x) {956; CHECK-LABEL: @add_umin_simplify(957; CHECK-NEXT:    ret i32 42958;959  %a = add nuw i32 %x, 42960  %c = icmp ult i32 %a, 42961  %r = select i1 %c, i32 %a, i32 42962  ret i32 %r963}964 965; Negative test966; TODO: assert that instsimplify always gets this?967 968define i32 @add_umin_simplify2(i32 %x) {969; CHECK-LABEL: @add_umin_simplify2(970; CHECK-NEXT:    ret i32 42971;972  %a = add nuw i32 %x, 43973  %c = icmp ult i32 %a, 42974  %r = select i1 %c, i32 %a, i32 42975  ret i32 %r976}977 978; Negative test979 980define i32 @add_umin_wrong_pred(i32 %x) {981; CHECK-LABEL: @add_umin_wrong_pred(982; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 15983; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42)984; CHECK-NEXT:    ret i32 [[R]]985;986  %a = add nuw i32 %x, 15987  %c = icmp slt i32 %a, 42988  %r = select i1 %c, i32 %a, i32 42989  ret i32 %r990}991 992; Negative test993 994define i32 @add_umin_wrong_wrap(i32 %x) {995; CHECK-LABEL: @add_umin_wrong_wrap(996; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 15997; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42)998; CHECK-NEXT:    ret i32 [[R]]999;1000  %a = add nsw i32 %x, 151001  %c = icmp ult i32 %a, 421002  %r = select i1 %c, i32 %a, i32 421003  ret i32 %r1004}1005 1006; Negative test1007 1008define i32 @add_umin_extra_use(i32 %x, ptr %p) {1009; CHECK-LABEL: @add_umin_extra_use(1010; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 151011; CHECK-NEXT:    store i32 [[A]], ptr [[P:%.*]], align 41012; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42)1013; CHECK-NEXT:    ret i32 [[R]]1014;1015  %a = add nuw i32 %x, 151016  store i32 %a, ptr %p1017  %c = icmp ult i32 %a, 421018  %r = select i1 %c, i32 %a, i32 421019  ret i32 %r1020}1021 1022define <2 x i16> @add_umin_vec(<2 x i16> %x) {1023; CHECK-LABEL: @add_umin_vec(1024; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> splat (i16 225))1025; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i16> [[TMP1]], splat (i16 15)1026; CHECK-NEXT:    ret <2 x i16> [[R]]1027;1028  %a = add nuw <2 x i16> %x, <i16 15, i16 15>1029  %c = icmp ult <2 x i16> %a, <i16 240, i16 240>1030  %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240>1031  ret <2 x i16> %r1032}1033 1034define i37 @add_umax(i37 %x) {1035; CHECK-LABEL: @add_umax(1036; CHECK-NEXT:    [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 37)1037; CHECK-NEXT:    [[R:%.*]] = add nuw i37 [[TMP1]], 51038; CHECK-NEXT:    ret i37 [[R]]1039;1040  %a = add nuw i37 %x, 51041  %c = icmp ugt i37 %a, 421042  %r = select i1 %c, i37 %a, i37 421043  ret i37 %r1044}1045 1046define i37 @add_umax_constant_limit(i37 %x) {1047; CHECK-LABEL: @add_umax_constant_limit(1048; CHECK-NEXT:    [[TMP1:%.*]] = call i37 @llvm.umax.i37(i37 [[X:%.*]], i37 1)1049; CHECK-NEXT:    [[R:%.*]] = add nuw i37 [[TMP1]], 811050; CHECK-NEXT:    ret i37 [[R]]1051;1052  %a = add nuw i37 %x, 811053  %c = icmp ugt i37 %a, 821054  %r = select i1 %c, i37 %a, i37 821055  ret i37 %r1056}1057 1058; Negative test1059; TODO: assert that instsimplify always gets this?1060 1061define i37 @add_umax_simplify(i37 %x) {1062; CHECK-LABEL: @add_umax_simplify(1063; CHECK-NEXT:    [[A:%.*]] = add nuw i37 [[X:%.*]], 421064; CHECK-NEXT:    ret i37 [[A]]1065;1066  %a = add nuw i37 %x, 421067  %c = icmp ugt i37 %a, 421068  %r = select i1 %c, i37 %a, i37 421069  ret i37 %r1070}1071 1072; Negative test1073; TODO: assert that instsimplify always gets this?1074 1075define i32 @add_umax_simplify2(i32 %x) {1076; CHECK-LABEL: @add_umax_simplify2(1077; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 571078; CHECK-NEXT:    ret i32 [[A]]1079;1080  %a = add nuw i32 %x, 571081  %c = icmp ugt i32 %a, 561082  %r = select i1 %c, i32 %a, i32 561083  ret i32 %r1084}1085 1086; Negative test1087 1088define i32 @add_umax_wrong_pred(i32 %x) {1089; CHECK-LABEL: @add_umax_wrong_pred(1090; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 151091; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42)1092; CHECK-NEXT:    ret i32 [[R]]1093;1094  %a = add nuw i32 %x, 151095  %c = icmp sgt i32 %a, 421096  %r = select i1 %c, i32 %a, i32 421097  ret i32 %r1098}1099 1100; Negative test1101 1102; Without the nuw that would allow pushing the add through the umax, the1103; add + icmp ugt combination can be interpreted as a range check, and would1104; normally be canonicalized to use ult instead. However, this is not done when1105; used as part of a umax to avoid breaking the SPF pattern.1106define i32 @add_umax_wrong_wrap(i32 %x) {1107; CHECK-LABEL: @add_umax_wrong_wrap(1108; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 151109; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42)1110; CHECK-NEXT:    ret i32 [[R]]1111;1112  %a = add nsw i32 %x, 151113  %c = icmp ugt i32 %a, 421114  %r = select i1 %c, i32 %a, i32 421115  ret i32 %r1116}1117 1118; Negative test1119 1120define i32 @add_umax_extra_use(i32 %x, ptr %p) {1121; CHECK-LABEL: @add_umax_extra_use(1122; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 151123; CHECK-NEXT:    store i32 [[A]], ptr [[P:%.*]], align 41124; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42)1125; CHECK-NEXT:    ret i32 [[R]]1126;1127  %a = add nuw i32 %x, 151128  store i32 %a, ptr %p1129  %c = icmp ugt i32 %a, 421130  %r = select i1 %c, i32 %a, i32 421131  ret i32 %r1132}1133 1134define <2 x i33> @add_umax_vec(<2 x i33> %x) {1135; CHECK-LABEL: @add_umax_vec(1136; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i33> @llvm.umax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> splat (i33 235))1137; CHECK-NEXT:    [[R:%.*]] = add nuw <2 x i33> [[TMP1]], splat (i33 5)1138; CHECK-NEXT:    ret <2 x i33> [[R]]1139;1140  %a = add nuw <2 x i33> %x, <i33 5, i33 5>1141  %c = icmp ugt <2 x i33> %a, <i33 240, i33 240>1142  %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240>1143  ret <2 x i33> %r1144}1145 1146define i8 @PR14613_umin(i8 %x) {1147; CHECK-LABEL: @PR14613_umin(1148; CHECK-NEXT:    [[NARROW:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X:%.*]], i8 15)1149; CHECK-NEXT:    ret i8 [[NARROW]]1150;1151  %u4 = zext i8 %x to i321152  %u5 = add nuw nsw i32 %u4, 151153  %u6 = icmp ult i32 %u5, 2551154  %u7 = select i1 %u6, i32 %u5, i32 2551155  %r = trunc i32 %u7 to i81156  ret i8 %r1157}1158 1159define i8 @PR14613_umax(i8 %x) {1160; CHECK-LABEL: @PR14613_umax(1161; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 -16)1162; CHECK-NEXT:    [[U7:%.*]] = add nsw i8 [[TMP1]], 151163; CHECK-NEXT:    ret i8 [[U7]]1164;1165  %u4 = zext i8 %x to i321166  %u5 = add nuw nsw i32 %u4, 151167  %u6 = icmp ugt i32 %u5, 2551168  %u7 = select i1 %u6, i32 %u5, i32 2551169  %r = trunc i32 %u7 to i81170  ret i8 %r1171}1172 1173define i32 @add_smin(i32 %x) {1174; CHECK-LABEL: @add_smin(1175; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 27)1176; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], 151177; CHECK-NEXT:    ret i32 [[R]]1178;1179  %a = add nsw i32 %x, 151180  %c = icmp slt i32 %a, 421181  %r = select i1 %c, i32 %a, i32 421182  ret i32 %r1183}1184 1185define i32 @add_smin_constant_limit(i32 %x) {1186; CHECK-LABEL: @add_smin_constant_limit(1187; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 2147483646)1188; CHECK-NEXT:    [[R:%.*]] = add nsw i32 [[TMP1]], -31189; CHECK-NEXT:    ret i32 [[R]]1190;1191  %a = add nsw i32 %x, -31192  %c = icmp slt i32 %a, 21474836431193  %r = select i1 %c, i32 %a, i32 21474836431194  ret i32 %r1195}1196 1197; Negative test1198; TODO: assert that instsimplify always gets this?1199 1200define i32 @add_smin_simplify(i32 %x) {1201; CHECK-LABEL: @add_smin_simplify(1202; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], -31203; CHECK-NEXT:    ret i32 [[A]]1204;1205  %a = add nsw i32 %x, -31206  %c = icmp slt i32 %a, 21474836441207  %r = select i1 %c, i32 %a, i32 21474836441208  ret i32 %r1209}1210 1211; Negative test1212; TODO: assert that instsimplify always gets this?1213 1214define i32 @add_smin_simplify2(i32 %x) {1215; CHECK-LABEL: @add_smin_simplify2(1216; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], -31217; CHECK-NEXT:    ret i32 [[A]]1218;1219  %a = add nsw i32 %x, -31220  %c = icmp slt i32 %a, 21474836451221  %r = select i1 %c, i32 %a, i32 21474836451222  ret i32 %r1223}1224 1225; Negative test1226 1227define i32 @add_smin_wrong_pred(i32 %x) {1228; CHECK-LABEL: @add_smin_wrong_pred(1229; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 151230; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 42)1231; CHECK-NEXT:    ret i32 [[R]]1232;1233  %a = add nsw i32 %x, 151234  %c = icmp ult i32 %a, 421235  %r = select i1 %c, i32 %a, i32 421236  ret i32 %r1237}1238 1239; Negative test1240 1241define i32 @add_smin_wrong_wrap(i32 %x) {1242; CHECK-LABEL: @add_smin_wrong_wrap(1243; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 151244; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42)1245; CHECK-NEXT:    ret i32 [[R]]1246;1247  %a = add nuw i32 %x, 151248  %c = icmp slt i32 %a, 421249  %r = select i1 %c, i32 %a, i32 421250  ret i32 %r1251}1252 1253; Negative test1254 1255define i32 @add_smin_extra_use(i32 %x, ptr %p) {1256; CHECK-LABEL: @add_smin_extra_use(1257; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 151258; CHECK-NEXT:    store i32 [[A]], ptr [[P:%.*]], align 41259; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 42)1260; CHECK-NEXT:    ret i32 [[R]]1261;1262  %a = add nsw i32 %x, 151263  store i32 %a, ptr %p1264  %c = icmp slt i32 %a, 421265  %r = select i1 %c, i32 %a, i32 421266  ret i32 %r1267}1268 1269define <2 x i16> @add_smin_vec(<2 x i16> %x) {1270; CHECK-LABEL: @add_smin_vec(1271; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> splat (i16 225))1272; CHECK-NEXT:    [[R:%.*]] = add nsw <2 x i16> [[TMP1]], splat (i16 15)1273; CHECK-NEXT:    ret <2 x i16> [[R]]1274;1275  %a = add nsw <2 x i16> %x, <i16 15, i16 15>1276  %c = icmp slt <2 x i16> %a, <i16 240, i16 240>1277  %r = select <2 x i1> %c, <2 x i16> %a, <2 x i16> <i16 240, i16 240>1278  ret <2 x i16> %r1279}1280 1281define i37 @add_smax(i37 %x) {1282; CHECK-LABEL: @add_smax(1283; CHECK-NEXT:    [[TMP1:%.*]] = call i37 @llvm.smax.i37(i37 [[X:%.*]], i37 37)1284; CHECK-NEXT:    [[R:%.*]] = add nuw nsw i37 [[TMP1]], 51285; CHECK-NEXT:    ret i37 [[R]]1286;1287  %a = add nsw i37 %x, 51288  %c = icmp sgt i37 %a, 421289  %r = select i1 %c, i37 %a, i37 421290  ret i37 %r1291}1292 1293define i8 @add_smax_constant_limit(i8 %x) {1294; CHECK-LABEL: @add_smax_constant_limit(1295; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127)1296; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[TMP1]], 1251297; CHECK-NEXT:    ret i8 [[R]]1298;1299  %a = add nsw i8 %x, 1251300  %c = icmp sgt i8 %a, -21301  %r = select i1 %c, i8 %a, i8 -21302  ret i8 %r1303}1304 1305; Negative test1306; TODO: assert that instsimplify always gets this?1307 1308define i8 @add_smax_simplify(i8 %x) {1309; CHECK-LABEL: @add_smax_simplify(1310; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X:%.*]], 1261311; CHECK-NEXT:    ret i8 [[A]]1312;1313  %a = add nsw i8 %x, 1261314  %c = icmp sgt i8 %a, -21315  %r = select i1 %c, i8 %a, i8 -21316  ret i8 %r1317}1318 1319; Negative test1320; TODO: assert that instsimplify always gets this?1321 1322define i8 @add_smax_simplify2(i8 %x) {1323; CHECK-LABEL: @add_smax_simplify2(1324; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X:%.*]], 1271325; CHECK-NEXT:    ret i8 [[A]]1326;1327  %a = add nsw i8 %x, 1271328  %c = icmp sgt i8 %a, -21329  %r = select i1 %c, i8 %a, i8 -21330  ret i8 %r1331}1332 1333; Negative test1334 1335define i32 @add_smax_wrong_pred(i32 %x) {1336; CHECK-LABEL: @add_smax_wrong_pred(1337; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 151338; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 42)1339; CHECK-NEXT:    ret i32 [[R]]1340;1341  %a = add nsw i32 %x, 151342  %c = icmp ugt i32 %a, 421343  %r = select i1 %c, i32 %a, i32 421344  ret i32 %r1345}1346 1347; Negative test1348 1349define i32 @add_smax_wrong_wrap(i32 %x) {1350; CHECK-LABEL: @add_smax_wrong_wrap(1351; CHECK-NEXT:    [[A:%.*]] = add nuw i32 [[X:%.*]], 151352; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42)1353; CHECK-NEXT:    ret i32 [[R]]1354;1355  %a = add nuw i32 %x, 151356  %c = icmp sgt i32 %a, 421357  %r = select i1 %c, i32 %a, i32 421358  ret i32 %r1359}1360 1361; Negative test1362 1363define i32 @add_smax_extra_use(i32 %x, ptr %p) {1364; CHECK-LABEL: @add_smax_extra_use(1365; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], 151366; CHECK-NEXT:    store i32 [[A]], ptr [[P:%.*]], align 41367; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 42)1368; CHECK-NEXT:    ret i32 [[R]]1369;1370  %a = add nsw i32 %x, 151371  store i32 %a, ptr %p1372  %c = icmp sgt i32 %a, 421373  %r = select i1 %c, i32 %a, i32 421374  ret i32 %r1375}1376 1377define <2 x i33> @add_smax_vec(<2 x i33> %x) {1378; CHECK-LABEL: @add_smax_vec(1379; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i33> @llvm.smax.v2i33(<2 x i33> [[X:%.*]], <2 x i33> splat (i33 235))1380; CHECK-NEXT:    [[R:%.*]] = add nuw nsw <2 x i33> [[TMP1]], splat (i33 5)1381; CHECK-NEXT:    ret <2 x i33> [[R]]1382;1383  %a = add nsw <2 x i33> %x, <i33 5, i33 5>1384  %c = icmp sgt <2 x i33> %a, <i33 240, i33 240>1385  %r = select <2 x i1> %c, <2 x i33> %a, <2 x i33> <i33 240, i33 240>1386  ret <2 x i33> %r1387}1388 1389define i8 @PR14613_smin(i8 %x) {1390; CHECK-LABEL: @PR14613_smin(1391; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[X:%.*]], i8 40)1392; CHECK-NEXT:    [[NARROW:%.*]] = add nsw i8 [[TMP1]], 151393; CHECK-NEXT:    ret i8 [[NARROW]]1394;1395  %u4 = sext i8 %x to i321396  %u5 = add nuw nsw i32 %u4, 151397  %u6 = icmp slt i32 %u5, 551398  %u7 = select i1 %u6, i32 %u5, i32 551399  %r = trunc i32 %u7 to i81400  ret i8 %r1401}1402 1403define i8 @PR14613_smax(i8 %x) {1404; CHECK-LABEL: @PR14613_smax(1405; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 40)1406; CHECK-NEXT:    [[NARROW:%.*]] = add nuw i8 [[TMP1]], 151407; CHECK-NEXT:    ret i8 [[NARROW]]1408;1409  %u4 = sext i8 %x to i321410  %u5 = add nuw nsw i32 %u4, 151411  %u6 = icmp sgt i32 %u5, 551412  %u7 = select i1 %u6, i32 %u5, i32 551413  %r = trunc i32 %u7 to i81414  ret i8 %r1415}1416 1417define i8 @PR46271(<2 x i8> %x) {1418; CHECK-LABEL: @PR46271(1419; CHECK-NEXT:    [[NOT:%.*]] = call <2 x i8> @llvm.smax.v2i8(<2 x i8> [[X:%.*]], <2 x i8> splat (i8 -1))1420; CHECK-NEXT:    [[R:%.*]] = extractelement <2 x i8> [[NOT]], i64 11421; CHECK-NEXT:    [[R1:%.*]] = xor i8 [[R]], -11422; CHECK-NEXT:    ret i8 [[R1]]1423;1424  %a = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>1425  %b = select <2 x i1> %a, <2 x i8> %x, <2 x i8> <i8 poison, i8 -1>1426  %not = xor <2 x i8> %b, <i8 poison, i8 -1>1427  %r = extractelement <2 x i8> %not, i32 11428  ret i8 %r1429}1430 1431define i32 @twoway_clamp_lt(i32 %num) {1432; CHECK-LABEL: @twoway_clamp_lt(1433; CHECK-NEXT:  entry:1434; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[NUM:%.*]], 137681435; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP0]], i32 13767, i32 137681436; CHECK-NEXT:    ret i32 [[R]]1437;1438entry:1439  %cmp1 = icmp slt i32 %num, 137681440  %s1 = select i1 %cmp1, i32 %num, i32 137681441  %cmp2 = icmp sgt i32 %s1, 137671442  %r = select i1 %cmp2, i32 %s1, i32 137671443  ret i32 %r1444}1445 1446define i32 @twoway_clamp_gt(i32 %num) {1447; CHECK-LABEL: @twoway_clamp_gt(1448; CHECK-NEXT:  entry:1449; CHECK-NEXT:    [[S1:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 13767)1450; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[S1]], i32 13768)1451; CHECK-NEXT:    ret i32 [[R]]1452;1453entry:1454  %cmp1 = icmp sgt i32 %num, 137671455  %s1 = select i1 %cmp1, i32 %num, i32 137671456  %cmp2 = icmp slt i32 %s1, 137681457  %r = select i1 %cmp2, i32 %s1, i32 137681458  ret i32 %r1459}1460 1461define i32 @twoway_clamp_gt_nonconst(i32 %num, i32 %k) {1462; CHECK-LABEL: @twoway_clamp_gt_nonconst(1463; CHECK-NEXT:  entry:1464; CHECK-NEXT:    [[K1:%.*]] = add i32 [[K:%.*]], 11465; CHECK-NEXT:    [[S1:%.*]] = call i32 @llvm.smax.i32(i32 [[NUM:%.*]], i32 [[K]])1466; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[S1]], i32 [[K1]])1467; CHECK-NEXT:    ret i32 [[R]]1468;1469entry:1470  %k1 = add i32 %k, 11471  %cmp1 = icmp sgt i32 %num, %k1472  %s1 = select i1 %cmp1, i32 %num, i32 %k1473  %cmp2 = icmp slt i32 %s1, %k11474  %r = select i1 %cmp2, i32 %s1, i32 %k11475  ret i32 %r1476}1477 1478define i32 @test_umax_smax1(i32 %x) {1479; CHECK-LABEL: @test_umax_smax1(1480; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 1)1481; CHECK-NEXT:    ret i32 [[UMAX]]1482;1483  %smax = call i32 @llvm.smax.i32(i32 %x, i32 0)1484  %umax = call i32 @llvm.umax.i32(i32 %smax, i32 1)1485  ret i32 %umax1486}1487 1488define i32 @test_umax_smax2(i32 %x) {1489; CHECK-LABEL: @test_umax_smax2(1490; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 20)1491; CHECK-NEXT:    ret i32 [[SMAX]]1492;1493  %smax = call i32 @llvm.smax.i32(i32 %x, i32 20)1494  %umax = call i32 @llvm.umax.i32(i32 %smax, i32 10)1495  ret i32 %umax1496}1497 1498define <2 x i32> @test_umax_smax_vec(<2 x i32> %x) {1499; CHECK-LABEL: @test_umax_smax_vec(1500; CHECK-NEXT:    [[UMAX:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 1, i32 20>)1501; CHECK-NEXT:    ret <2 x i32> [[UMAX]]1502;1503  %smax = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %x, <2 x i32> <i32 0, i32 20>)1504  %umax = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %smax, <2 x i32> <i32 1, i32 10>)1505  ret <2 x i32> %umax1506}1507 1508define i32 @test_smin_umin1(i32 %x) {1509; CHECK-LABEL: @test_smin_umin1(1510; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 10)1511; CHECK-NEXT:    ret i32 [[SMIN]]1512;1513  %smin = call i32 @llvm.umin.i32(i32 %x, i32 10)1514  %umin = call i32 @llvm.smin.i32(i32 %smin, i32 20)1515  ret i32 %umin1516}1517 1518define i32 @test_smin_umin2(i32 %x) {1519; CHECK-LABEL: @test_smin_umin2(1520; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 10)1521; CHECK-NEXT:    ret i32 [[UMIN]]1522;1523  %smin = call i32 @llvm.umin.i32(i32 %x, i32 20)1524  %umin = call i32 @llvm.smin.i32(i32 %smin, i32 10)1525  ret i32 %umin1526}1527 1528define <2 x i32> @test_smin_umin_vec(<2 x i32> %x) {1529; CHECK-LABEL: @test_smin_umin_vec(1530; CHECK-NEXT:    [[UMIN:%.*]] = call <2 x i32> @llvm.umin.v2i32(<2 x i32> [[X:%.*]], <2 x i32> splat (i32 10))1531; CHECK-NEXT:    ret <2 x i32> [[UMIN]]1532;1533  %smin = call <2 x i32> @llvm.umin.v2i32(<2 x i32> %x, <2 x i32> <i32 10, i32 20>)1534  %umin = call <2 x i32> @llvm.smin.v2i32(<2 x i32> %smin, <2 x i32> <i32 20, i32 10>)1535  ret <2 x i32> %umin1536}1537 1538; Negative tests1539 1540define i32 @test_umax_smax3(i32 %x) {1541; CHECK-LABEL: @test_umax_smax3(1542; CHECK-NEXT:    ret i32 -11543;1544  %smax = call i32 @llvm.smax.i32(i32 %x, i32 0)1545  %umax = call i32 @llvm.umax.i32(i32 %smax, i32 -1)1546  ret i32 %umax1547}1548 1549define i32 @test_umax_smax4(i32 %x) {1550; CHECK-LABEL: @test_umax_smax4(1551; CHECK-NEXT:    [[SMAX:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 -20)1552; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[SMAX]], i32 10)1553; CHECK-NEXT:    ret i32 [[UMAX]]1554;1555  %smax = call i32 @llvm.smax.i32(i32 %x, i32 -20)1556  %umax = call i32 @llvm.umax.i32(i32 %smax, i32 10)1557  ret i32 %umax1558}1559 1560define i32 @test_smin_umin3(i32 %x) {1561; CHECK-LABEL: @test_smin_umin3(1562; CHECK-NEXT:    ret i32 -201563;1564  %smin = call i32 @llvm.umin.i32(i32 %x, i32 10)1565  %umin = call i32 @llvm.smin.i32(i32 %smin, i32 -20)1566  ret i32 %umin1567}1568 1569define i32 @test_smin_umin4(i32 %x) {1570; CHECK-LABEL: @test_smin_umin4(1571; CHECK-NEXT:    [[SMIN:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 -20)1572; CHECK-NEXT:    [[UMIN:%.*]] = call i32 @llvm.smin.i32(i32 [[SMIN]], i32 10)1573; CHECK-NEXT:    ret i32 [[UMIN]]1574;1575  %smin = call i32 @llvm.umin.i32(i32 %x, i32 -20)1576  %umin = call i32 @llvm.smin.i32(i32 %smin, i32 10)1577  ret i32 %umin1578}1579 1580define i32 @test_umax_nonminmax(i32 %x) {1581; CHECK-LABEL: @test_umax_nonminmax(1582; CHECK-NEXT:    [[Y:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1583; CHECK-NEXT:    [[UMAX:%.*]] = call i32 @llvm.umax.i32(i32 [[Y]], i32 1)1584; CHECK-NEXT:    ret i32 [[UMAX]]1585;1586  %y = call i32 @llvm.ctpop.i32(i32 %x)1587  %umax = call i32 @llvm.umax.i32(i32 %y, i32 1)1588  ret i32 %umax1589}1590 1591define <2 x i32> @test_umax_smax_vec_neg(<2 x i32> %x) {1592; CHECK-LABEL: @test_umax_smax_vec_neg(1593; CHECK-NEXT:    [[SMAX:%.*]] = call <2 x i32> @llvm.smax.v2i32(<2 x i32> [[X:%.*]], <2 x i32> <i32 0, i32 -20>)1594; CHECK-NEXT:    [[UMAX:%.*]] = call <2 x i32> @llvm.umax.v2i32(<2 x i32> [[SMAX]], <2 x i32> <i32 1, i32 10>)1595; CHECK-NEXT:    ret <2 x i32> [[UMAX]]1596;1597  %smax = call <2 x i32> @llvm.smax.v2i32(<2 x i32> %x, <2 x i32> <i32 0, i32 -20>)1598  %umax = call <2 x i32> @llvm.umax.v2i32(<2 x i32> %smax, <2 x i32> <i32 1, i32 10>)1599  ret <2 x i32> %umax1600}1601 1602define i32 @test_smin_sub1_nsw(i32 %x, i32 %w) {1603; CHECK-LABEL: @test_smin_sub1_nsw(1604; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[W:%.*]], -11605; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[SUB]])1606; CHECK-NEXT:    ret i32 [[R]]1607;1608  %cmp = icmp slt i32 %x, %w1609  %sub = add nsw i32 %w, -11610  %r = select i1 %cmp, i32 %x, i32 %sub1611  ret i32 %r1612}1613 1614define i32 @test_smax_add1_nsw(i32 %x, i32 %w) {1615; CHECK-LABEL: @test_smax_add1_nsw(1616; CHECK-NEXT:    [[X2:%.*]] = add nsw i32 [[W:%.*]], 11617; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 [[X2]])1618; CHECK-NEXT:    ret i32 [[R]]1619;1620  %cmp = icmp sgt i32 %x, %w1621  %add = add nsw i32 %w, 11622  %r = select i1 %cmp, i32 %x, i32 %add1623  ret i32 %r1624}1625 1626define i32 @test_umax_add1_nuw(i32 %x, i32 %w) {1627; CHECK-LABEL: @test_umax_add1_nuw(1628; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[W:%.*]], 11629; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[ADD]])1630; CHECK-NEXT:    ret i32 [[R]]1631;1632  %cmp = icmp ugt i32 %x, %w1633  %add = add nuw i32 %w, 11634  %r = select i1 %cmp, i32 %x, i32 %add1635  ret i32 %r1636}1637 1638define i32 @test_umin_sub1_nuw(i32 %x, i32 range(i32 1, 0) %w) {1639; CHECK-LABEL: @test_umin_sub1_nuw(1640; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[W:%.*]], -11641; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[SUB]])1642; CHECK-NEXT:    ret i32 [[R]]1643;1644  %cmp = icmp ult i32 %x, %w1645  %sub = add i32 %w, -11646  %r = select i1 %cmp, i32 %x, i32 %sub1647  ret i32 %r1648}1649 1650define i32 @test_smin_sub1_nsw_swapped(i32 %x, i32 %w) {1651; CHECK-LABEL: @test_smin_sub1_nsw_swapped(1652; CHECK-NEXT:    [[SUB:%.*]] = add nsw i32 [[W:%.*]], -11653; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smin.i32(i32 [[X:%.*]], i32 [[SUB]])1654; CHECK-NEXT:    ret i32 [[R]]1655;1656  %cmp = icmp sgt i32 %w, %x1657  %sub = add nsw i32 %w, -11658  %r = select i1 %cmp, i32 %x, i32 %sub1659  ret i32 %r1660}1661 1662define i32 @test_smax_add1_nsw_swapped(i32 %x, i32 %w) {1663; CHECK-LABEL: @test_smax_add1_nsw_swapped(1664; CHECK-NEXT:    [[X2:%.*]] = add nsw i32 [[W:%.*]], 11665; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 [[X2]])1666; CHECK-NEXT:    ret i32 [[R]]1667;1668  %cmp = icmp slt i32 %w, %x1669  %add = add nsw i32 %w, 11670  %r = select i1 %cmp, i32 %x, i32 %add1671  ret i32 %r1672}1673 1674define i32 @test_umax_add1_nuw_swapped(i32 %x, i32 %w) {1675; CHECK-LABEL: @test_umax_add1_nuw_swapped(1676; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[W:%.*]], 11677; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[ADD]])1678; CHECK-NEXT:    ret i32 [[R]]1679;1680  %cmp = icmp ult i32 %w, %x1681  %add = add nuw i32 %w, 11682  %r = select i1 %cmp, i32 %x, i32 %add1683  ret i32 %r1684}1685 1686define i32 @test_umin_sub1_nuw_swapped(i32 %x, i32 range(i32 1, 0) %w) {1687; CHECK-LABEL: @test_umin_sub1_nuw_swapped(1688; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[W:%.*]], -11689; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[SUB]])1690; CHECK-NEXT:    ret i32 [[R]]1691;1692  %cmp = icmp ugt i32 %w, %x1693  %sub = add i32 %w, -11694  %r = select i1 %cmp, i32 %x, i32 %sub1695  ret i32 %r1696}1697 1698define <2 x i16> @test_smin_sub1_nsw_vec(<2 x i16> %x, <2 x i16> %w) {1699; CHECK-LABEL: @test_smin_sub1_nsw_vec(1700; CHECK-NEXT:    [[SUB:%.*]] = add nsw <2 x i16> [[W:%.*]], splat (i16 -1)1701; CHECK-NEXT:    [[R:%.*]] = call <2 x i16> @llvm.smin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> [[SUB]])1702; CHECK-NEXT:    ret <2 x i16> [[R]]1703;1704  %cmp = icmp slt <2 x i16> %x, %w1705  %sub = add nsw <2 x i16> %w, splat (i16 -1)1706  %r = select <2 x i1> %cmp, <2 x i16> %x, <2 x i16> %sub1707  ret <2 x i16> %r1708}1709 1710define <2 x i16> @test_smax_add1_nsw_vec(<2 x i16> %x, <2 x i16> %w) {1711; CHECK-LABEL: @test_smax_add1_nsw_vec(1712; CHECK-NEXT:    [[ADD:%.*]] = add nsw <2 x i16> [[W:%.*]], splat (i16 1)1713; CHECK-NEXT:    [[R:%.*]] = call <2 x i16> @llvm.smax.v2i16(<2 x i16> [[X:%.*]], <2 x i16> [[ADD]])1714; CHECK-NEXT:    ret <2 x i16> [[R]]1715;1716  %cmp = icmp sgt <2 x i16> %x, %w1717  %add = add nsw <2 x i16> %w, splat (i16 1)1718  %r = select <2 x i1> %cmp, <2 x i16> %x, <2 x i16> %add1719  ret <2 x i16> %r1720}1721 1722define <2 x i16> @test_umax_add1_nuw_vec(<2 x i16> %x, <2 x i16> %w) {1723; CHECK-LABEL: @test_umax_add1_nuw_vec(1724; CHECK-NEXT:    [[ADD:%.*]] = add nuw <2 x i16> [[W:%.*]], splat (i16 1)1725; CHECK-NEXT:    [[R:%.*]] = call <2 x i16> @llvm.umax.v2i16(<2 x i16> [[X:%.*]], <2 x i16> [[ADD]])1726; CHECK-NEXT:    ret <2 x i16> [[R]]1727;1728  %cmp = icmp ugt <2 x i16> %x, %w1729  %add = add nuw <2 x i16> %w, splat (i16 1)1730  %r = select <2 x i1> %cmp, <2 x i16> %x, <2 x i16> %add1731  ret <2 x i16> %r1732}1733 1734define <2 x i16> @test_umin_sub1_nuw_vec(<2 x i16> %x, <2 x i16> range(i16 1, 0) %w) {1735; CHECK-LABEL: @test_umin_sub1_nuw_vec(1736; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i16> [[W:%.*]], splat (i16 -1)1737; CHECK-NEXT:    [[R:%.*]] = call <2 x i16> @llvm.umin.v2i16(<2 x i16> [[X:%.*]], <2 x i16> [[SUB]])1738; CHECK-NEXT:    ret <2 x i16> [[R]]1739;1740  %cmp = icmp ult <2 x i16> %x, %w1741  %sub = add <2 x i16> %w, splat (i16 -1)1742  %r = select <2 x i1> %cmp, <2 x i16> %x, <2 x i16> %sub1743  ret <2 x i16> %r1744}1745 1746 1747define i32 @test_smin_sub1_nsw_drop_flags(i32 %x, i32 %w) {1748; CHECK-LABEL: @test_smin_sub1_nsw_drop_flags(1749; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[W:%.*]]1750; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 -11751; CHECK-NEXT:    ret i32 [[R]]1752;1753  %cmp = icmp slt i32 %x, %w1754  %sub = add nsw nuw i32 %w, -11755  %r = select i1 %cmp, i32 %x, i32 %sub1756  ret i32 %r1757}1758 1759define i32 @test_smax_add1_nsw_drop_flags(i32 %x, i32 %w) {1760; CHECK-LABEL: @test_smax_add1_nsw_drop_flags(1761; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[W:%.*]], 11762; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.smax.i32(i32 [[X:%.*]], i32 [[ADD]])1763; CHECK-NEXT:    ret i32 [[R]]1764;1765  %cmp = icmp sgt i32 %x, %w1766  %add = add nsw nuw i32 %w, 11767  %r = select i1 %cmp, i32 %x, i32 %add1768  ret i32 %r1769}1770 1771define i32 @test_umax_add1_nuw_drop_flags(i32 %x, i32 %w) {1772; CHECK-LABEL: @test_umax_add1_nuw_drop_flags(1773; CHECK-NEXT:    [[ADD:%.*]] = add nuw i32 [[W:%.*]], 11774; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[ADD]])1775; CHECK-NEXT:    ret i32 [[R]]1776;1777  %cmp = icmp ugt i32 %x, %w1778  %add = add nuw nsw i32 %w, 11779  %r = select i1 %cmp, i32 %x, i32 %add1780  ret i32 %r1781}1782 1783define i32 @test_umin_sub1_nuw_drop_flags(i32 %x, i32 range(i32 1, 0) %w) {1784; CHECK-LABEL: @test_umin_sub1_nuw_drop_flags(1785; CHECK-NEXT:    [[SUB:%.*]] = add i32 [[W:%.*]], -11786; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[SUB]])1787; CHECK-NEXT:    ret i32 [[R]]1788;1789  %cmp = icmp ult i32 %x, %w1790  %sub = add nsw i32 %w, -11791  %r = select i1 %cmp, i32 %x, i32 %sub1792  ret i32 %r1793}1794 1795;; Confirm we don't crash on these cases.1796define i32 @test_smin_or_neg1_nsw(i32 %x, i32 %w) {1797; CHECK-LABEL: @test_smin_or_neg1_nsw(1798; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[W:%.*]]1799; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 -11800; CHECK-NEXT:    ret i32 [[R]]1801;1802  %cmp = icmp slt i32 %x, %w1803  %sub = or disjoint i32 %w, -11804  %r = select i1 %cmp, i32 %x, i32 %sub1805  ret i32 %r1806}1807 1808define i32 @test_smax_or_1_nsw(i32 %x, i32 %w) {1809; CHECK-LABEL: @test_smax_or_1_nsw(1810; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[W:%.*]]1811; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i32 [[W]], 11812; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[ADD]]1813; CHECK-NEXT:    ret i32 [[R]]1814;1815  %cmp = icmp sgt i32 %x, %w1816  %add = or disjoint i32 %w, 11817  %r = select i1 %cmp, i32 %x, i32 %add1818  ret i32 %r1819}1820 1821define i32 @test_umax_or_1_nuw(i32 %x, i32 %w) {1822; CHECK-LABEL: @test_umax_or_1_nuw(1823; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[W:%.*]]1824; CHECK-NEXT:    [[ADD:%.*]] = or disjoint i32 [[W]], 11825; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[ADD]]1826; CHECK-NEXT:    ret i32 [[R]]1827;1828  %cmp = icmp ugt i32 %x, %w1829  %add = or disjoint i32 %w, 11830  %r = select i1 %cmp, i32 %x, i32 %add1831  ret i32 %r1832}1833 1834define i32 @test_umin_or_neg1_nuw(i32 %x, i32 range(i32 1, 0) %w) {1835; CHECK-LABEL: @test_umin_or_neg1_nuw(1836; CHECK-NEXT:    [[CMP:%.*]] = icmp ult i32 [[X:%.*]], [[W:%.*]]1837; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP]], i32 [[X]], i32 -11838; CHECK-NEXT:    ret i32 [[R]]1839;1840  %cmp = icmp ult i32 %x, %w1841  %sub = or disjoint i32 %w, -11842  %r = select i1 %cmp, i32 %x, i32 %sub1843  ret i32 %r1844}1845