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