1000 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare i8 @llvm.abs.i8(i8, i1)5declare i32 @llvm.abs.i32(i32, i1)6declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)7declare <3 x i82> @llvm.abs.v3i82(<3 x i82>, i1)8declare <2 x i8> @llvm.abs.v2i8(<2 x i8>, i1)9declare void @llvm.assume(i1)10declare void @use(i32)11 12define i8 @test_abs_abs_a_mul_b_i8(i8 %a, i8 %b) {13; CHECK-LABEL: @test_abs_abs_a_mul_b_i8(14; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[B:%.*]], [[A:%.*]]15; CHECK-NEXT: [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)16; CHECK-NEXT: ret i8 [[ABS2]]17;18 %abs1 = call i8 @llvm.abs.i8(i8 %a, i1 true)19 %mul = mul i8 %abs1, %b20 %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)21 ret i8 %abs222}23 24define i8 @test_abs_a_mul_abs_b_i8(i8 %a, i8 %b) {25; CHECK-LABEL: @test_abs_a_mul_abs_b_i8(26; CHECK-NEXT: [[A1:%.*]] = urem i8 123, [[A:%.*]]27; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[A1]], [[B:%.*]]28; CHECK-NEXT: [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)29; CHECK-NEXT: ret i8 [[ABS2]]30;31 %a1 = urem i8 123, %a ; thwart complexity-based canonicalization32 %abs1 = call i8 @llvm.abs.i8(i8 %b, i1 true)33 %mul = mul i8 %a1, %abs134 %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)35 ret i8 %abs236}37 38define i32 @test_abs_abs_a_mul_b_i32(i32 %a, i32 %b) {39; CHECK-LABEL: @test_abs_abs_a_mul_b_i32(40; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]41; CHECK-NEXT: [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)42; CHECK-NEXT: ret i32 [[ABS2]]43;44 %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 true)45 %mul = mul i32 %abs1, %b46 %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 true)47 ret i32 %abs248}49 50define i32 @test_abs_abs_a_mul_b_i32_abs_false_true(i32 %a, i32 %b) {51; CHECK-LABEL: @test_abs_abs_a_mul_b_i32_abs_false_true(52; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]53; CHECK-NEXT: [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 true)54; CHECK-NEXT: ret i32 [[ABS2]]55;56 %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 false)57 %mul = mul i32 %abs1, %b58 %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 true)59 ret i32 %abs260}61 62define i32 @test_abs_abs_a_mul_b_i32_abs_true_false(i32 %a, i32 %b) {63; CHECK-LABEL: @test_abs_abs_a_mul_b_i32_abs_true_false(64; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]65; CHECK-NEXT: [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 false)66; CHECK-NEXT: ret i32 [[ABS2]]67;68 %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 true)69 %mul = mul i32 %abs1, %b70 %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 false)71 ret i32 %abs272}73 74define i32 @test_abs_abs_a_mul_b_i32_abs_false_false(i32 %a, i32 %b) {75; CHECK-LABEL: @test_abs_abs_a_mul_b_i32_abs_false_false(76; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[B:%.*]], [[A:%.*]]77; CHECK-NEXT: [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[TMP1]], i1 false)78; CHECK-NEXT: ret i32 [[ABS2]]79;80 %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 false)81 %mul = mul i32 %abs1, %b82 %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 false)83 ret i32 %abs284}85 86; this should work87define i8 @test_nsw_with_true(i8 %a, i8 %b) {88; CHECK-LABEL: @test_nsw_with_true(89; CHECK-NEXT: [[TMP1:%.*]] = mul nsw i8 [[B:%.*]], [[A:%.*]]90; CHECK-NEXT: [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 true)91; CHECK-NEXT: ret i8 [[ABS2]]92;93 %abs1 = call i8 @llvm.abs.i8(i8 %a, i1 false)94 %mul = mul nsw i8 %abs1, %b95 %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 true)96 ret i8 %abs297}98 99; this should't propagate the nsw100define i8 @test_nsw_with_false(i8 %a, i8 %b) {101; CHECK-LABEL: @test_nsw_with_false(102; CHECK-NEXT: [[TMP1:%.*]] = mul i8 [[B:%.*]], [[A:%.*]]103; CHECK-NEXT: [[ABS2:%.*]] = call i8 @llvm.abs.i8(i8 [[TMP1]], i1 false)104; CHECK-NEXT: ret i8 [[ABS2]]105;106 %abs1 = call i8 @llvm.abs.i8(i8 %a, i1 false)107 %mul = mul nsw i8 %abs1, %b108 %abs2 = call i8 @llvm.abs.i8(i8 %mul, i1 false)109 ret i8 %abs2110}111 112define i32 @test_abs_abs_a_mul_b_more_one_use(i32 %a, i32 %b) {113; CHECK-LABEL: @test_abs_abs_a_mul_b_more_one_use(114; CHECK-NEXT: [[ABS1:%.*]] = call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 true)115; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[ABS1]], [[B:%.*]]116; CHECK-NEXT: [[ABS2:%.*]] = call i32 @llvm.abs.i32(i32 [[MUL]], i1 false)117; CHECK-NEXT: call void @use(i32 [[MUL]])118; CHECK-NEXT: ret i32 [[ABS2]]119;120 %abs1 = call i32 @llvm.abs.i32(i32 %a, i1 true)121 %mul = mul i32 %abs1, %b122 %abs2 = call i32 @llvm.abs.i32(i32 %mul, i1 false)123 call void @use(i32 %mul)124 ret i32 %abs2125}126 127define <2 x i8> @test_abs_abs_a_mul_b_vector_i8(<2 x i8> %a, <2 x i8> %b) {128; CHECK-LABEL: @test_abs_abs_a_mul_b_vector_i8(129; CHECK-NEXT: [[TMP1:%.*]] = mul <2 x i8> [[B:%.*]], [[A:%.*]]130; CHECK-NEXT: [[ABS2:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[TMP1]], i1 true)131; CHECK-NEXT: ret <2 x i8> [[ABS2]]132;133 %abs = call <2 x i8> @llvm.abs.v2i8(<2 x i8> %a, i1 true)134 %mul = mul <2 x i8> %abs, %b135 %abs2 = call <2 x i8> @llvm.abs.v2i8(<2 x i8> %mul, i1 true)136 ret <2 x i8> %abs2137}138 139; abs preserves trailing zeros so the second and is unneeded140define i32 @abs_trailing_zeros(i32 %x) {141; CHECK-LABEL: @abs_trailing_zeros(142; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], -4143; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[AND]], i1 false)144; CHECK-NEXT: ret i32 [[ABS]]145;146 %and = and i32 %x, -4147 %abs = call i32 @llvm.abs.i32(i32 %and, i1 false)148 %and2 = and i32 %abs, -2149 ret i32 %and2150}151 152define <4 x i32> @abs_trailing_zeros_vec(<4 x i32> %x) {153; CHECK-LABEL: @abs_trailing_zeros_vec(154; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[X:%.*]], <i32 -4, i32 -8, i32 -16, i32 -32>155; CHECK-NEXT: [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[AND]], i1 false)156; CHECK-NEXT: ret <4 x i32> [[ABS]]157;158 %and = and <4 x i32> %x, <i32 -4, i32 -8, i32 -16, i32 -32>159 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %and, i1 false)160 %and2 = and <4 x i32> %abs, <i32 -2, i32 -2, i32 -2, i32 -2>161 ret <4 x i32> %and2162}163 164; negative test, can't remove the second and based on trailing zeroes.165; FIXME: Could remove the first and using demanded bits.166define i32 @abs_trailing_zeros_negative(i32 %x) {167; CHECK-LABEL: @abs_trailing_zeros_negative(168; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], -2169; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[AND]], i1 false)170; CHECK-NEXT: [[AND2:%.*]] = and i32 [[ABS]], -4171; CHECK-NEXT: ret i32 [[AND2]]172;173 %and = and i32 %x, -2174 %abs = call i32 @llvm.abs.i32(i32 %and, i1 false)175 %and2 = and i32 %abs, -4176 ret i32 %and2177}178 179define <4 x i32> @abs_trailing_zeros_negative_vec(<4 x i32> %x) {180; CHECK-LABEL: @abs_trailing_zeros_negative_vec(181; CHECK-NEXT: [[AND:%.*]] = and <4 x i32> [[X:%.*]], splat (i32 -2)182; CHECK-NEXT: [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[AND]], i1 false)183; CHECK-NEXT: [[AND2:%.*]] = and <4 x i32> [[ABS]], splat (i32 -4)184; CHECK-NEXT: ret <4 x i32> [[AND2]]185;186 %and = and <4 x i32> %x, <i32 -2, i32 -2, i32 -2, i32 -2>187 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %and, i1 false)188 %and2 = and <4 x i32> %abs, <i32 -4, i32 -4, i32 -4, i32 -4>189 ret <4 x i32> %and2190}191 192; Make sure we infer this add doesn't overflow. The input to the abs has 3193; sign bits, the abs reduces this to 2 sign bits.194define i32 @abs_signbits(i30 %x) {195; CHECK-LABEL: @abs_signbits(196; CHECK-NEXT: [[TMP1:%.*]] = call i30 @llvm.abs.i30(i30 [[X:%.*]], i1 false)197; CHECK-NEXT: [[NARROW:%.*]] = add nuw i30 [[TMP1]], 1198; CHECK-NEXT: [[ADD:%.*]] = zext i30 [[NARROW]] to i32199; CHECK-NEXT: ret i32 [[ADD]]200;201 %ext = sext i30 %x to i32202 %abs = call i32 @llvm.abs.i32(i32 %ext, i1 false)203 %add = add i32 %abs, 1204 ret i32 %add205}206 207define <4 x i32> @abs_signbits_vec(<4 x i30> %x) {208; CHECK-LABEL: @abs_signbits_vec(209; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i30> @llvm.abs.v4i30(<4 x i30> [[X:%.*]], i1 false)210; CHECK-NEXT: [[NARROW:%.*]] = add nuw <4 x i30> [[TMP1]], splat (i30 1)211; CHECK-NEXT: [[ADD:%.*]] = zext <4 x i30> [[NARROW]] to <4 x i32>212; CHECK-NEXT: ret <4 x i32> [[ADD]]213;214 %ext = sext <4 x i30> %x to <4 x i32>215 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %ext, i1 false)216 %add = add <4 x i32> %abs, <i32 1, i32 1, i32 1, i32 1>217 ret <4 x i32> %add218}219 220define i32 @abs_of_neg(i32 %x) {221; CHECK-LABEL: @abs_of_neg(222; CHECK-NEXT: [[B:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)223; CHECK-NEXT: ret i32 [[B]]224;225 %a = sub i32 0, %x226 %b = call i32 @llvm.abs.i32(i32 %a, i1 false)227 ret i32 %b228}229 230define <4 x i32> @abs_of_neg_vec(<4 x i32> %x) {231; CHECK-LABEL: @abs_of_neg_vec(232; CHECK-NEXT: [[B:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 true)233; CHECK-NEXT: ret <4 x i32> [[B]]234;235 %a = sub nsw <4 x i32> zeroinitializer, %x236 %b = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %a, i1 false)237 ret <4 x i32> %b238}239 240define i32 @abs_of_select_neg_true_val(i1 %b, i32 %x) {241; CHECK-LABEL: @abs_of_select_neg_true_val(242; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)243; CHECK-NEXT: ret i32 [[ABS]]244;245 %neg = sub i32 0, %x246 %sel = select i1 %b, i32 %neg, i32 %x247 %abs = call i32 @llvm.abs.i32(i32 %sel, i1 true)248 ret i32 %abs249}250 251define <4 x i32> @abs_of_select_neg_false_val(<4 x i1> %b, <4 x i32> %x) {252; CHECK-LABEL: @abs_of_select_neg_false_val(253; CHECK-NEXT: [[ABS:%.*]] = call <4 x i32> @llvm.abs.v4i32(<4 x i32> [[X:%.*]], i1 false)254; CHECK-NEXT: ret <4 x i32> [[ABS]]255;256 %neg = sub <4 x i32> zeroinitializer, %x257 %sel = select <4 x i1> %b, <4 x i32> %x, <4 x i32> %neg258 %abs = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %sel, i1 false)259 ret <4 x i32> %abs260}261 262define i32 @abs_dom_cond_nopoison(i32 %x) {263; CHECK-LABEL: @abs_dom_cond_nopoison(264; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1265; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]266; CHECK: true:267; CHECK-NEXT: ret i32 [[X]]268; CHECK: false:269; CHECK-NEXT: [[A2:%.*]] = sub i32 0, [[X]]270; CHECK-NEXT: ret i32 [[A2]]271;272 %cmp = icmp sge i32 %x, 0273 br i1 %cmp, label %true, label %false274 275true:276 %a1 = call i32 @llvm.abs.i32(i32 %x, i1 false)277 ret i32 %a1278 279false:280 %a2 = call i32 @llvm.abs.i32(i32 %x, i1 false)281 ret i32 %a2282}283 284define i32 @abs_dom_cond_poison(i32 %x) {285; CHECK-LABEL: @abs_dom_cond_poison(286; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1287; CHECK-NEXT: br i1 [[CMP]], label [[TRUE:%.*]], label [[FALSE:%.*]]288; CHECK: true:289; CHECK-NEXT: ret i32 [[X]]290; CHECK: false:291; CHECK-NEXT: [[A2:%.*]] = sub nsw i32 0, [[X]]292; CHECK-NEXT: ret i32 [[A2]]293;294 %cmp = icmp sge i32 %x, 0295 br i1 %cmp, label %true, label %false296 297true:298 %a1 = call i32 @llvm.abs.i32(i32 %x, i1 true)299 ret i32 %a1300 301false:302 %a2 = call i32 @llvm.abs.i32(i32 %x, i1 true)303 ret i32 %a2304}305 306; Abs argument non-neg based on known bits.307 308define i32 @zext_abs(i31 %x) {309; CHECK-LABEL: @zext_abs(310; CHECK-NEXT: [[ZEXT:%.*]] = zext i31 [[X:%.*]] to i32311; CHECK-NEXT: ret i32 [[ZEXT]]312;313 %zext = zext i31 %x to i32314 %abs = call i32 @llvm.abs.i32(i32 %zext, i1 false)315 ret i32 %abs316}317 318define <3 x i82> @lshr_abs(<3 x i82> %x) {319; CHECK-LABEL: @lshr_abs(320; CHECK-NEXT: [[LSHR:%.*]] = lshr <3 x i82> [[X:%.*]], splat (i82 1)321; CHECK-NEXT: ret <3 x i82> [[LSHR]]322;323 %lshr = lshr <3 x i82> %x, <i82 1, i82 1, i82 1>324 %abs = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %lshr, i1 true)325 ret <3 x i82> %abs326}327 328define i32 @and_abs(i32 %x) {329; CHECK-LABEL: @and_abs(330; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 2147483644331; CHECK-NEXT: ret i32 [[AND]]332;333 %and = and i32 %x, 2147483644334 %abs = call i32 @llvm.abs.i32(i32 %and, i1 true)335 ret i32 %abs336}337 338define <3 x i82> @select_abs(<3 x i1> %cond) {339; CHECK-LABEL: @select_abs(340; CHECK-NEXT: [[SEL:%.*]] = select <3 x i1> [[COND:%.*]], <3 x i82> zeroinitializer, <3 x i82> <i82 2147483647, i82 42, i82 1>341; CHECK-NEXT: ret <3 x i82> [[SEL]]342;343 %sel = select <3 x i1> %cond, <3 x i82> zeroinitializer, <3 x i82> <i82 2147483647, i82 42, i82 1>344 %abs = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %sel, i1 false)345 ret <3 x i82> %abs346}347 348define i32 @assume_abs(i32 %x) {349; CHECK-LABEL: @assume_abs(350; CHECK-NEXT: [[ASSUME:%.*]] = icmp sgt i32 [[X:%.*]], -1351; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])352; CHECK-NEXT: ret i32 [[X]]353;354 %assume = icmp sge i32 %x, 0355 call void @llvm.assume(i1 %assume)356 %abs = call i32 @llvm.abs.i32(i32 %x, i1 true)357 ret i32 %abs358}359 360; Abs argument negative based on known bits.361 362define i32 @abs_assume_neg(i32 %x) {363; CHECK-LABEL: @abs_assume_neg(364; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0365; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])366; CHECK-NEXT: [[ABS:%.*]] = sub i32 0, [[X]]367; CHECK-NEXT: ret i32 [[ABS]]368;369 %cmp = icmp slt i32 %x, 0370 call void @llvm.assume(i1 %cmp)371 %abs = call i32 @llvm.abs.i32(i32 %x, i1 false)372 ret i32 %abs373}374 375define i32 @abs_known_neg(i16 %x) {376; CHECK-LABEL: @abs_known_neg(377; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[X:%.*]] to i32378; CHECK-NEXT: [[NEG_NEG:%.*]] = add nuw nsw i32 [[EXT]], 1379; CHECK-NEXT: ret i32 [[NEG_NEG]]380;381 %ext = zext i16 %x to i32382 %neg = sub nsw i32 -1, %ext383 %abs = call i32 @llvm.abs.i32(i32 %neg, i1 false)384 ret i32 %abs385}386 387define i1 @abs_eq_int_min_poison(i8 %x) {388; CHECK-LABEL: @abs_eq_int_min_poison(389; CHECK-NEXT: ret i1 false390;391 %abs = call i8 @llvm.abs.i8(i8 %x, i1 true)392 %cmp = icmp eq i8 %abs, -128393 ret i1 %cmp394}395 396define i1 @abs_ne_int_min_poison(i8 %x) {397; CHECK-LABEL: @abs_ne_int_min_poison(398; CHECK-NEXT: ret i1 true399;400 %abs = call i8 @llvm.abs.i8(i8 %x, i1 true)401 %cmp = icmp ne i8 %abs, -128402 ret i1 %cmp403}404 405define i1 @abs_eq_int_min_nopoison(i8 %x) {406; CHECK-LABEL: @abs_eq_int_min_nopoison(407; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128408; CHECK-NEXT: ret i1 [[CMP]]409;410 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)411 %cmp = icmp eq i8 %abs, -128412 ret i1 %cmp413}414 415define i1 @abs_ne_int_min_nopoison(i8 %x) {416; CHECK-LABEL: @abs_ne_int_min_nopoison(417; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[X:%.*]], -128418; CHECK-NEXT: ret i1 [[CMP]]419;420 %abs = call i8 @llvm.abs.i8(i8 %x, i1 false)421 %cmp = icmp ne i8 %abs, -128422 ret i1 %cmp423}424 425define i32 @abs_sext(i8 %x) {426; CHECK-LABEL: @abs_sext(427; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)428; CHECK-NEXT: [[A:%.*]] = zext i8 [[TMP1]] to i32429; CHECK-NEXT: ret i32 [[A]]430;431 %s = sext i8 %x to i32432 %a = call i32 @llvm.abs.i32(i32 %s, i1 0)433 ret i32 %a434}435 436define <3 x i82> @abs_nsw_sext(<3 x i7> %x) {437; CHECK-LABEL: @abs_nsw_sext(438; CHECK-NEXT: [[TMP1:%.*]] = call <3 x i7> @llvm.abs.v3i7(<3 x i7> [[X:%.*]], i1 false)439; CHECK-NEXT: [[A:%.*]] = zext <3 x i7> [[TMP1]] to <3 x i82>440; CHECK-NEXT: ret <3 x i82> [[A]]441;442 %s = sext <3 x i7> %x to <3 x i82>443 %a = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %s, i1 1)444 ret <3 x i82> %a445}446 447define i32 @abs_sext_extra_use(i8 %x, ptr %p) {448; CHECK-LABEL: @abs_sext_extra_use(449; CHECK-NEXT: [[S:%.*]] = sext i8 [[X:%.*]] to i32450; CHECK-NEXT: store i32 [[S]], ptr [[P:%.*]], align 4451; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[S]], i1 false)452; CHECK-NEXT: ret i32 [[A]]453;454 %s = sext i8 %x to i32455 store i32 %s, ptr %p456 %a = call i32 @llvm.abs.i32(i32 %s, i1 0)457 ret i32 %a458}459 460; PR48816461 462define i8 @trunc_abs_sext(i8 %x) {463; CHECK-LABEL: @trunc_abs_sext(464; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)465; CHECK-NEXT: ret i8 [[TMP1]]466;467 %s = sext i8 %x to i32468 %a = tail call i32 @llvm.abs.i32(i32 %s, i1 true)469 %t = trunc i32 %a to i8470 ret i8 %t471}472 473define <4 x i8> @trunc_abs_sext_vec(<4 x i8> %x) {474; CHECK-LABEL: @trunc_abs_sext_vec(475; CHECK-NEXT: [[TMP1:%.*]] = call <4 x i8> @llvm.abs.v4i8(<4 x i8> [[X:%.*]], i1 false)476; CHECK-NEXT: ret <4 x i8> [[TMP1]]477;478 %s = sext <4 x i8> %x to <4 x i32>479 %a = tail call <4 x i32> @llvm.abs.v4i32(<4 x i32> %s, i1 true)480 %t = trunc <4 x i32> %a to <4 x i8>481 ret <4 x i8> %t482}483 484; abs() doesn't change the low bit.485 486define i32 @demand_low_bit(i32 %x) {487; CHECK-LABEL: @demand_low_bit(488; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], 1489; CHECK-NEXT: ret i32 [[R]]490;491 %a = call i32 @llvm.abs.i32(i32 %x, i1 false)492 %r = and i32 %a, 1493 ret i32 %r494}495 496; Int min behavior doesn't affect the transform.497 498define <3 x i82> @demand_low_bit_int_min_is_poison(<3 x i82> %x) {499; CHECK-LABEL: @demand_low_bit_int_min_is_poison(500; CHECK-NEXT: [[R:%.*]] = shl <3 x i82> [[X:%.*]], splat (i82 81)501; CHECK-NEXT: ret <3 x i82> [[R]]502;503 %a = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %x, i1 true)504 %r = shl <3 x i82> %a, <i82 81, i82 81, i82 81>505 ret <3 x i82> %r506}507 508; Negative test - only low bit is allowed.509 510define i32 @demand_low_bits(i32 %x) {511; CHECK-LABEL: @demand_low_bits(512; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)513; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], 3514; CHECK-NEXT: ret i32 [[R]]515;516 %a = call i32 @llvm.abs.i32(i32 %x, i1 false)517 %r = and i32 %a, 3518 ret i32 %r519}520 521define i32 @srem_by_2_int_min_is_poison(i32 %x) {522; CHECK-LABEL: @srem_by_2_int_min_is_poison(523; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], 1524; CHECK-NEXT: ret i32 [[R]]525;526 %s = srem i32 %x, 2527 %r = call i32 @llvm.abs.i32(i32 %s, i1 true)528 ret i32 %r529}530 531define <3 x i82> @srem_by_2(<3 x i82> %x, ptr %p) {532; CHECK-LABEL: @srem_by_2(533; CHECK-NEXT: [[S:%.*]] = srem <3 x i82> [[X:%.*]], splat (i82 2)534; CHECK-NEXT: store <3 x i82> [[S]], ptr [[P:%.*]], align 32535; CHECK-NEXT: [[R:%.*]] = and <3 x i82> [[X]], splat (i82 1)536; CHECK-NEXT: ret <3 x i82> [[R]]537;538 %s = srem <3 x i82> %x, <i82 2, i82 2, i82 2>539 store <3 x i82> %s, ptr %p540 %r = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %s, i1 false)541 ret <3 x i82> %r542}543 544; TODO: A more general transform could sink the srem and turn it into urem.545 546define i32 @srem_by_3(i32 %x) {547; CHECK-LABEL: @srem_by_3(548; CHECK-NEXT: [[S:%.*]] = srem i32 [[X:%.*]], 3549; CHECK-NEXT: [[R:%.*]] = call i32 @llvm.abs.i32(i32 [[S]], i1 true)550; CHECK-NEXT: ret i32 [[R]]551;552 %s = srem i32 %x, 3553 %r = call i32 @llvm.abs.i32(i32 %s, i1 true)554 ret i32 %r555}556 557; Test from https://github.com/llvm/llvm-project/issues/54132.558define i32 @sub_abs_gt(i32 %x, i32 %y) {559; CHECK-LABEL: @sub_abs_gt(560; CHECK-NEXT: entry:561; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]562; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]563; CHECK: cond.true:564; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]565; CHECK-NEXT: br label [[COND_END]]566; CHECK: cond.end:567; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]568; CHECK-NEXT: ret i32 [[R]]569;570entry:571 %cmp = icmp sgt i32 %x, %y572 br i1 %cmp, label %cond.true, label %cond.end573 574cond.true:575 %sub = sub nsw i32 %x, %y576 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)577 br label %cond.end578 579cond.end:580 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]581 ret i32 %r582}583 584; https://alive2.llvm.org/ce/z/VSumU5585define i32 @sub_abs_sgeT(i32 %x, i32 %y) {586; CHECK-LABEL: @sub_abs_sgeT(587; CHECK-NEXT: entry:588; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]589; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]590; CHECK: cond.true:591; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X]], [[Y]]592; CHECK-NEXT: br label [[COND_END]]593; CHECK: cond.end:594; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]595; CHECK-NEXT: ret i32 [[R]]596;597entry:598 %cmp = icmp sge i32 %x, %y599 br i1 %cmp, label %cond.true, label %cond.end600 601cond.true:602 %sub = sub nsw i32 %x, %y603 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)604 br label %cond.end605 606cond.end:607 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]608 ret i32 %r609}610 611; https://alive2.llvm.org/ce/z/BSM6UR612define i32 @sub_abs_sgeT_swap(i32 %x, i32 %y) {613; CHECK-LABEL: @sub_abs_sgeT_swap(614; CHECK-NEXT: entry:615; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp slt i32 [[Y:%.*]], [[X:%.*]]616; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]617; CHECK: cond.true:618; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]619; CHECK-NEXT: br label [[COND_END]]620; CHECK: cond.end:621; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]622; CHECK-NEXT: ret i32 [[R]]623;624entry:625 %cmp = icmp sge i32 %y, %x ; swap the operands626 br i1 %cmp, label %cond.true, label %cond.end627 628cond.true:629 %sub = sub nsw i32 %x, %y630 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)631 br label %cond.end632 633cond.end:634 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]635 ret i32 %r636}637 638; https://alive2.llvm.org/ce/z/BSM6UR639define i32 @sub_abs_sgeT_false(i32 %x, i32 %y) {640; CHECK-LABEL: @sub_abs_sgeT_false(641; CHECK-NEXT: entry:642; CHECK-NEXT: [[CMP_NOT_NOT:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]643; CHECK-NEXT: br i1 [[CMP_NOT_NOT]], label [[COND_FALSE:%.*]], label [[COND_END:%.*]]644; CHECK: cond.false:645; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]646; CHECK-NEXT: br label [[COND_END]]647; CHECK: cond.end:648; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_FALSE]] ], [ 0, [[ENTRY:%.*]] ]649; CHECK-NEXT: ret i32 [[R]]650;651entry:652 %cmp.not = icmp sge i32 %x, %y653 br i1 %cmp.not, label %cond.end, label %cond.false654 655cond.false:656 %sub = sub nsw i32 %x, %y657 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true) ; abs in false case658 br label %cond.end659 660cond.end:661 %r = phi i32 [ %0, %cond.false ], [ 0, %entry ]662 ret i32 %r663}664 665define i32 @sub_abs_lt(i32 %x, i32 %y) {666; CHECK-LABEL: @sub_abs_lt(667; CHECK-NEXT: entry:668; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]669; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]670; CHECK: cond.true:671; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]672; CHECK-NEXT: br label [[COND_END]]673; CHECK: cond.end:674; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]675; CHECK-NEXT: ret i32 [[R]]676;677entry:678 %cmp = icmp slt i32 %x, %y679 br i1 %cmp, label %cond.true, label %cond.end680 681cond.true:682 %sub = sub nsw i32 %x, %y683 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)684 br label %cond.end685 686cond.end:687 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]688 ret i32 %r689}690 691; https://alive2.llvm.org/ce/z/9wQo6G692define i32 @sub_abs_sle(i32 %x, i32 %y) {693; CHECK-LABEL: @sub_abs_sle(694; CHECK-NEXT: entry:695; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]696; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]697; CHECK: cond.true:698; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i32 [[Y]], [[X]]699; CHECK-NEXT: br label [[COND_END]]700; CHECK: cond.end:701; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]702; CHECK-NEXT: ret i32 [[R]]703;704entry:705 %cmp = icmp sle i32 %x, %y706 br i1 %cmp, label %cond.true, label %cond.end707 708cond.true:709 %sub = sub nsw i32 %x, %y710 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)711 br label %cond.end712 713cond.end:714 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]715 ret i32 %r716}717 718; https://alive2.llvm.org/ce/z/xlpSO0719define i8 @sub_abs_sleF(i8 %x, i8 %y) {720; CHECK-LABEL: @sub_abs_sleF(721; CHECK-NEXT: entry:722; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]723; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]724; CHECK: cond.true:725; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i8 [[Y]], [[X]]726; CHECK-NEXT: br label [[COND_END]]727; CHECK: cond.end:728; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]729; CHECK-NEXT: ret i8 [[R]]730;731entry:732 %cmp = icmp sle i8 %x, %y733 br i1 %cmp, label %cond.true, label %cond.end734 735cond.true:736 %sub = sub nsw i8 %x, %y737 %0 = call i8 @llvm.abs.i8(i8 %sub, i1 false)738 br label %cond.end739 740cond.end:741 %r = phi i8 [ %0, %cond.true ], [ 0, %entry ]742 ret i8 %r743}744 745define i8 @sub_abs_sleT(i8 %x, i8 %y) {746; CHECK-LABEL: @sub_abs_sleT(747; CHECK-NEXT: entry:748; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt i8 [[X:%.*]], [[Y:%.*]]749; CHECK-NEXT: br i1 [[CMP_NOT]], label [[COND_END:%.*]], label [[COND_TRUE:%.*]]750; CHECK: cond.true:751; CHECK-NEXT: [[SUB_NEG:%.*]] = sub nsw i8 [[Y]], [[X]]752; CHECK-NEXT: br label [[COND_END]]753; CHECK: cond.end:754; CHECK-NEXT: [[R:%.*]] = phi i8 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]755; CHECK-NEXT: ret i8 [[R]]756;757entry:758 %cmp = icmp sle i8 %x, %y759 br i1 %cmp, label %cond.true, label %cond.end760 761cond.true:762 %sub = sub nsw i8 %x, %y763 %0 = call i8 @llvm.abs.i8(i8 %sub, i1 true)764 br label %cond.end765 766cond.end:767 %r = phi i8 [ %0, %cond.true ], [ 0, %entry ]768 ret i8 %r769}770 771define i32 @sub_abs_lt_min_not_poison(i32 %x, i32 %y) {772; CHECK-LABEL: @sub_abs_lt_min_not_poison(773; CHECK-NEXT: entry:774; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], [[Y:%.*]]775; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]776; CHECK: cond.true:777; CHECK-NEXT: [[SUB_NEG:%.*]] = sub i32 [[Y]], [[X]]778; CHECK-NEXT: br label [[COND_END]]779; CHECK: cond.end:780; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[SUB_NEG]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]781; CHECK-NEXT: ret i32 [[R]]782;783entry:784 %cmp = icmp slt i32 %x, %y785 br i1 %cmp, label %cond.true, label %cond.end786 787cond.true:788 %sub = sub nsw i32 %x, %y789 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 false)790 br label %cond.end791 792cond.end:793 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]794 ret i32 %r795}796 797define i32 @sub_abs_wrong_pred(i32 %x, i32 %y) {798; CHECK-LABEL: @sub_abs_wrong_pred(799; CHECK-NEXT: entry:800; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], [[Y:%.*]]801; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]802; CHECK: cond.true:803; CHECK-NEXT: [[SUB:%.*]] = sub nuw nsw i32 [[X]], [[Y]]804; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)805; CHECK-NEXT: br label [[COND_END]]806; CHECK: cond.end:807; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[TMP0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]808; CHECK-NEXT: ret i32 [[R]]809;810entry:811 %cmp = icmp ugt i32 %x, %y812 br i1 %cmp, label %cond.true, label %cond.end813 814cond.true:815 %sub = sub nsw i32 %x, %y816 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)817 br label %cond.end818 819cond.end:820 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]821 ret i32 %r822}823 824define i32 @sub_abs_no_nsw(i32 %x, i32 %y) {825; CHECK-LABEL: @sub_abs_no_nsw(826; CHECK-NEXT: entry:827; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]]828; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_END:%.*]]829; CHECK: cond.true:830; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X]], [[Y]]831; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 true)832; CHECK-NEXT: br label [[COND_END]]833; CHECK: cond.end:834; CHECK-NEXT: [[R:%.*]] = phi i32 [ [[TMP0]], [[COND_TRUE]] ], [ 0, [[ENTRY:%.*]] ]835; CHECK-NEXT: ret i32 [[R]]836;837entry:838 %cmp = icmp sgt i32 %x, %y839 br i1 %cmp, label %cond.true, label %cond.end840 841cond.true:842 %sub = sub i32 %x, %y843 %0 = call i32 @llvm.abs.i32(i32 %sub, i1 true)844 br label %cond.end845 846cond.end:847 %r = phi i32 [ %0, %cond.true ], [ 0, %entry ]848 ret i32 %r849}850 851; The AND should be removable based on range metadata. Make sure852; computeKnownBits doesn't lose this.853define i32 @abs_range_metadata(i32 %x) {854; CHECK-LABEL: @abs_range_metadata(855; CHECK-NEXT: [[B:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false), !range [[RNG0:![0-9]+]]856; CHECK-NEXT: ret i32 [[B]]857;858 %a = call i32 @llvm.abs.i32(i32 %x, i1 false), !range !1859 %b = and i32 %a, 15860 ret i32 %b861}862 863!1 = !{i32 0, i32 16}864 865define i32 @abs_diff(i32 %x, i32 %y) {866; CHECK-LABEL: @abs_diff(867; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]868; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 false)869; CHECK-NEXT: ret i32 [[COND]]870;871 %sub = sub nsw i32 %x, %y872 %cmp = icmp sgt i32 %x, %y873 %sub1 = sub i32 0, %sub874 %cond = select i1 %cmp, i32 %sub, i32 %sub1875 ret i32 %cond876}877 878define i32 @abs_diff_neg_no_nsw_neg(i32 %x, i32 %y) {879; CHECK-LABEL: @abs_diff_neg_no_nsw_neg(880; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]]881; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]882; CHECK-NEXT: [[SUB1:%.*]] = sub i32 0, [[SUB]]883; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[SUB1]]884; CHECK-NEXT: ret i32 [[COND]]885;886 %sub = sub i32 %x, %y887 %cmp = icmp sgt i32 %x, %y888 %sub1 = sub i32 0, %sub889 %cond = select i1 %cmp, i32 %sub, i32 %sub1890 ret i32 %cond891}892 893define i32 @abs_diff_neg(i32 %x, i32 %y) {894; CHECK-LABEL: @abs_diff_neg(895; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[Y:%.*]], [[X:%.*]]896; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]897; CHECK-NEXT: [[SUB1:%.*]] = sub i32 0, [[SUB]]898; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[SUB1]]899; CHECK-NEXT: ret i32 [[COND]]900;901 %sub = sub nsw i32 %y, %x902 %cmp = icmp sgt i32 %x, %y903 %sub1 = sub i32 0, %sub904 %cond = select i1 %cmp, i32 %sub, i32 %sub1905 ret i32 %cond906}907 908define i32 @abs_diff_neg_no_nsw(i32 %x, i32 %y) {909; CHECK-LABEL: @abs_diff_neg_no_nsw(910; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[Y:%.*]], [[X:%.*]]911; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], [[Y]]912; CHECK-NEXT: [[SUB1:%.*]] = sub i32 0, [[SUB]]913; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[SUB1]]914; CHECK-NEXT: ret i32 [[COND]]915;916 %sub = sub i32 %y, %x917 %cmp = icmp sgt i32 %x, %y918 %sub1 = sub i32 0, %sub919 %cond = select i1 %cmp, i32 %sub, i32 %sub1920 ret i32 %cond921}922 923define i32 @abs_diff_ge(i32 %x, i32 %y) {924; CHECK-LABEL: @abs_diff_ge(925; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]926; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 false)927; CHECK-NEXT: ret i32 [[COND]]928;929 %sub = sub nsw i32 %x, %y930 %cmp = icmp sge i32 %x, %y931 %sub1 = sub i32 0, %sub932 %cond = select i1 %cmp, i32 %sub, i32 %sub1933 ret i32 %cond934}935 936define i32 @abs_diff_slt_commute(i32 %x, i32 %y) {937; CHECK-LABEL: @abs_diff_slt_commute(938; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]939; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 false)940; CHECK-NEXT: ret i32 [[COND]]941;942 %sub = sub nsw i32 %x, %y943 %cmp = icmp slt i32 %y, %x944 %sub1 = sub i32 0, %sub945 %cond = select i1 %cmp, i32 %sub, i32 %sub1946 ret i32 %cond947}948 949define i32 @abs_diff_sge_same(i32 %x, i32 %y) {950; CHECK-LABEL: @abs_diff_sge_same(951; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]952; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 false)953; CHECK-NEXT: ret i32 [[COND]]954;955 %sub = sub nsw i32 %x, %y956 %cmp = icmp sge i32 %x, %y957 %sub1 = sub i32 0, %sub958 %cond = select i1 %cmp, i32 %sub, i32 %sub1959 ret i32 %cond960}961 962define i32 @abs_diff_sle_inverted(i32 %x, i32 %y) {963; CHECK-LABEL: @abs_diff_sle_inverted(964; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]965; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 false)966; CHECK-NEXT: ret i32 [[COND]]967;968 %sub = sub nsw i32 %x, %y969 %cmp = icmp sle i32 %x, %y970 %sub1 = sub i32 0, %sub971 %cond = select i1 %cmp, i32 %sub1, i32 %sub972 ret i32 %cond973}974 975define i32 @abs_diff_sle_commute(i32 %x, i32 %y) {976; CHECK-LABEL: @abs_diff_sle_commute(977; CHECK-NEXT: [[SUB:%.*]] = sub nsw i32 [[X:%.*]], [[Y:%.*]]978; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB]], i1 false)979; CHECK-NEXT: ret i32 [[COND]]980;981 %sub = sub nsw i32 %x, %y982 %cmp = icmp sle i32 %y, %x983 %sub1 = sub i32 0, %sub984 %cond = select i1 %cmp, i32 %sub, i32 %sub1985 ret i32 %cond986}987 988define i8 @abs_diff_sle_y_x(i8 %x, i8 %y) {989; CHECK-LABEL: @abs_diff_sle_y_x(990; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]]991; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB]], i1 false)992; CHECK-NEXT: ret i8 [[COND]]993;994 %sub = sub nsw i8 %x, %y995 %cmp = icmp sle i8 %y, %x996 %sub1 = sub i8 0, %sub997 %cond = select i1 %cmp, i8 %sub, i8 %sub1998 ret i8 %cond999}1000