992 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"5 6declare i32 @abs(i32)7declare i64 @labs(i64)8declare i64 @llabs(i64)9 10; Test that the abs library call simplifier works correctly.11; abs(x) -> x <s 0 ? -x : x.12 13define i32 @test_abs(i32 %x) {14; CHECK-LABEL: @test_abs(15; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 true)16; CHECK-NEXT: ret i32 [[RET]]17;18 %ret = call i32 @abs(i32 %x)19 ret i32 %ret20}21 22define i64 @test_labs(i64 %x) {23; CHECK-LABEL: @test_labs(24; CHECK-NEXT: [[RET:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true)25; CHECK-NEXT: ret i64 [[RET]]26;27 %ret = call i64 @labs(i64 %x)28 ret i64 %ret29}30 31define i64 @test_llabs(i64 %x) {32; CHECK-LABEL: @test_llabs(33; CHECK-NEXT: [[RET:%.*]] = call i64 @llvm.abs.i64(i64 [[X:%.*]], i1 true)34; CHECK-NEXT: ret i64 [[RET]]35;36 %ret = call i64 @llabs(i64 %x)37 ret i64 %ret38}39 40; We have a canonical form of abs to make CSE easier.41 42define i8 @abs_canonical_1(i8 %x) {43; CHECK-LABEL: @abs_canonical_1(44; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)45; CHECK-NEXT: ret i8 [[ABS]]46;47 %cmp = icmp sgt i8 %x, 048 %neg = sub i8 0, %x49 %abs = select i1 %cmp, i8 %x, i8 %neg50 ret i8 %abs51}52 53; Vectors should work too.54 55define <2 x i8> @abs_canonical_2(<2 x i8> %x) {56; CHECK-LABEL: @abs_canonical_2(57; CHECK-NEXT: [[ABS:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)58; CHECK-NEXT: ret <2 x i8> [[ABS]]59;60 %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>61 %neg = sub <2 x i8> zeroinitializer, %x62 %abs = select <2 x i1> %cmp, <2 x i8> %x, <2 x i8> %neg63 ret <2 x i8> %abs64}65 66; Even if a constant has poison elements.67 68define <2 x i8> @abs_canonical_2_vec_poison_elts(<2 x i8> %x) {69; CHECK-LABEL: @abs_canonical_2_vec_poison_elts(70; CHECK-NEXT: [[ABS:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)71; CHECK-NEXT: ret <2 x i8> [[ABS]]72;73 %cmp = icmp sgt <2 x i8> %x, <i8 poison, i8 -1>74 %neg = sub <2 x i8> zeroinitializer, %x75 %abs = select <2 x i1> %cmp, <2 x i8> %x, <2 x i8> %neg76 ret <2 x i8> %abs77}78 79; NSW should not change.80 81define i8 @abs_canonical_3(i8 %x) {82; CHECK-LABEL: @abs_canonical_3(83; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true)84; CHECK-NEXT: ret i8 [[ABS]]85;86 %cmp = icmp slt i8 %x, 087 %neg = sub nsw i8 0, %x88 %abs = select i1 %cmp, i8 %neg, i8 %x89 ret i8 %abs90}91 92define i8 @abs_canonical_4(i8 %x) {93; CHECK-LABEL: @abs_canonical_4(94; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)95; CHECK-NEXT: ret i8 [[ABS]]96;97 %cmp = icmp slt i8 %x, 198 %neg = sub i8 0, %x99 %abs = select i1 %cmp, i8 %neg, i8 %x100 ret i8 %abs101}102 103define i32 @abs_canonical_5(i8 %x) {104; CHECK-LABEL: @abs_canonical_5(105; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)106; CHECK-NEXT: [[ABS:%.*]] = zext i8 [[TMP1]] to i32107; CHECK-NEXT: ret i32 [[ABS]]108;109 %cmp = icmp sgt i8 %x, 0110 %conv = sext i8 %x to i32111 %neg = sub i32 0, %conv112 %abs = select i1 %cmp, i32 %conv, i32 %neg113 ret i32 %abs114}115 116define i32 @abs_canonical_6(i32 %a, i32 %b) {117; CHECK-LABEL: @abs_canonical_6(118; CHECK-NEXT: [[T1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]119; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[T1]], i1 false)120; CHECK-NEXT: ret i32 [[ABS]]121;122 %t1 = sub i32 %a, %b123 %cmp = icmp sgt i32 %t1, -1124 %t2 = sub i32 %b, %a125 %abs = select i1 %cmp, i32 %t1, i32 %t2126 ret i32 %abs127}128 129define <2 x i8> @abs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {130; CHECK-LABEL: @abs_canonical_7(131; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> [[A:%.*]], [[B:%.*]]132; CHECK-NEXT: [[ABS:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[T1]], i1 false)133; CHECK-NEXT: ret <2 x i8> [[ABS]]134;135 136 %t1 = sub <2 x i8> %a, %b137 %cmp = icmp sgt <2 x i8> %t1, <i8 -1, i8 -1>138 %t2 = sub <2 x i8> %b, %a139 %abs = select <2 x i1> %cmp, <2 x i8> %t1, <2 x i8> %t2140 ret <2 x i8> %abs141}142 143define i32 @abs_canonical_8(i32 %a) {144; CHECK-LABEL: @abs_canonical_8(145; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)146; CHECK-NEXT: ret i32 [[ABS]]147;148 %t = sub i32 0, %a149 %cmp = icmp slt i32 %t, 0150 %abs = select i1 %cmp, i32 %a, i32 %t151 ret i32 %abs152}153 154define i32 @abs_canonical_9(i32 %a, i32 %b) {155; CHECK-LABEL: @abs_canonical_9(156; CHECK-NEXT: [[T1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]157; CHECK-NEXT: [[T2:%.*]] = sub i32 [[B]], [[A]]158; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[T1]], i1 false)159; CHECK-NEXT: [[ADD:%.*]] = add i32 [[ABS]], [[T2]]160; CHECK-NEXT: ret i32 [[ADD]]161;162 %t1 = sub i32 %a, %b163 %cmp = icmp sgt i32 %t1, -1164 %t2 = sub i32 %b, %a165 %abs = select i1 %cmp, i32 %t1, i32 %t2166 %add = add i32 %abs, %t2 ; increase use count for %t2.167 ret i32 %add168}169 170define i32 @abs_canonical_10(i32 %a, i32 %b) {171; CHECK-LABEL: @abs_canonical_10(172; CHECK-NEXT: [[T1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]173; CHECK-NEXT: [[ABS:%.*]] = call i32 @llvm.abs.i32(i32 [[T1]], i1 false)174; CHECK-NEXT: ret i32 [[ABS]]175;176 %t2 = sub i32 %b, %a177 %t1 = sub i32 %a, %b178 %cmp = icmp sgt i32 %t1, -1179 %abs = select i1 %cmp, i32 %t1, i32 %t2180 ret i32 %abs181}182 183; We have a canonical form of nabs to make CSE easier.184 185define i8 @nabs_canonical_1(i8 %x) {186; CHECK-LABEL: @nabs_canonical_1(187; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)188; CHECK-NEXT: [[ABS:%.*]] = sub i8 0, [[TMP1]]189; CHECK-NEXT: ret i8 [[ABS]]190;191 %cmp = icmp sgt i8 %x, 0192 %neg = sub i8 0, %x193 %abs = select i1 %cmp, i8 %neg, i8 %x194 ret i8 %abs195}196 197; Vectors should work too.198 199define <2 x i8> @nabs_canonical_2(<2 x i8> %x) {200; CHECK-LABEL: @nabs_canonical_2(201; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)202; CHECK-NEXT: [[ABS:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]203; CHECK-NEXT: ret <2 x i8> [[ABS]]204;205 %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 -1>206 %neg = sub <2 x i8> zeroinitializer, %x207 %abs = select <2 x i1> %cmp, <2 x i8> %neg, <2 x i8> %x208 ret <2 x i8> %abs209}210 211; Even if a constant has poison elements.212 213define <2 x i8> @nabs_canonical_2_vec_poison_elts(<2 x i8> %x) {214; CHECK-LABEL: @nabs_canonical_2_vec_poison_elts(215; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)216; CHECK-NEXT: [[ABS:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]217; CHECK-NEXT: ret <2 x i8> [[ABS]]218;219 %cmp = icmp sgt <2 x i8> %x, <i8 -1, i8 poison>220 %neg = sub <2 x i8> zeroinitializer, %x221 %abs = select <2 x i1> %cmp, <2 x i8> %neg, <2 x i8> %x222 ret <2 x i8> %abs223}224 225; NSW should not change.226 227define i8 @nabs_canonical_3(i8 %x) {228; CHECK-LABEL: @nabs_canonical_3(229; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)230; CHECK-NEXT: [[ABS:%.*]] = sub i8 0, [[TMP1]]231; CHECK-NEXT: ret i8 [[ABS]]232;233 %cmp = icmp slt i8 %x, 0234 %neg = sub nsw i8 0, %x235 %abs = select i1 %cmp, i8 %x, i8 %neg236 ret i8 %abs237}238 239define i8 @nabs_canonical_4(i8 %x) {240; CHECK-LABEL: @nabs_canonical_4(241; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)242; CHECK-NEXT: [[ABS:%.*]] = sub i8 0, [[TMP1]]243; CHECK-NEXT: ret i8 [[ABS]]244;245 %cmp = icmp slt i8 %x, 1246 %neg = sub i8 0, %x247 %abs = select i1 %cmp, i8 %x, i8 %neg248 ret i8 %abs249}250 251define i32 @nabs_canonical_5(i8 %x) {252; CHECK-LABEL: @nabs_canonical_5(253; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)254; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32255; CHECK-NEXT: [[ABS:%.*]] = sub nsw i32 0, [[TMP2]]256; CHECK-NEXT: ret i32 [[ABS]]257;258 %cmp = icmp sgt i8 %x, 0259 %conv = sext i8 %x to i32260 %neg = sub i32 0, %conv261 %abs = select i1 %cmp, i32 %neg, i32 %conv262 ret i32 %abs263}264 265define i32 @nabs_canonical_6(i32 %a, i32 %b) {266; CHECK-LABEL: @nabs_canonical_6(267; CHECK-NEXT: [[T1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]268; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[T1]], i1 false)269; CHECK-NEXT: [[ABS:%.*]] = sub i32 0, [[TMP1]]270; CHECK-NEXT: ret i32 [[ABS]]271;272 %t1 = sub i32 %a, %b273 %cmp = icmp sgt i32 %t1, -1274 %t2 = sub i32 %b, %a275 %abs = select i1 %cmp, i32 %t2, i32 %t1276 ret i32 %abs277}278 279define <2 x i8> @nabs_canonical_7(<2 x i8> %a, <2 x i8 > %b) {280; CHECK-LABEL: @nabs_canonical_7(281; CHECK-NEXT: [[T1:%.*]] = sub <2 x i8> [[A:%.*]], [[B:%.*]]282; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[T1]], i1 false)283; CHECK-NEXT: [[ABS:%.*]] = sub <2 x i8> zeroinitializer, [[TMP1]]284; CHECK-NEXT: ret <2 x i8> [[ABS]]285;286 %t1 = sub <2 x i8> %a, %b287 %cmp = icmp sgt <2 x i8> %t1, <i8 -1, i8 -1>288 %t2 = sub <2 x i8> %b, %a289 %abs = select <2 x i1> %cmp, <2 x i8> %t2, <2 x i8> %t1290 ret <2 x i8> %abs291}292 293define i32 @nabs_canonical_8(i32 %a) {294; CHECK-LABEL: @nabs_canonical_8(295; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[A:%.*]], i1 false)296; CHECK-NEXT: [[ABS:%.*]] = sub i32 0, [[TMP1]]297; CHECK-NEXT: ret i32 [[ABS]]298;299 %t = sub i32 0, %a300 %cmp = icmp slt i32 %t, 0301 %abs = select i1 %cmp, i32 %t, i32 %a302 ret i32 %abs303}304 305define i32 @nabs_canonical_9(i32 %a, i32 %b) {306; CHECK-LABEL: @nabs_canonical_9(307; CHECK-NEXT: [[T1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]308; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[T1]], i1 false)309; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[A]], [[TMP1]]310; CHECK-NEXT: [[ADD:%.*]] = sub i32 [[B]], [[TMP2]]311; CHECK-NEXT: ret i32 [[ADD]]312;313 %t1 = sub i32 %a, %b314 %cmp = icmp sgt i32 %t1, -1315 %t2 = sub i32 %b, %a316 %abs = select i1 %cmp, i32 %t2, i32 %t1317 %add = add i32 %t2, %abs ; increase use count for %t2318 ret i32 %add319}320 321define i32 @nabs_canonical_10(i32 %a, i32 %b) {322; CHECK-LABEL: @nabs_canonical_10(323; CHECK-NEXT: [[T1:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]324; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.abs.i32(i32 [[T1]], i1 false)325; CHECK-NEXT: [[ABS:%.*]] = sub i32 0, [[TMP1]]326; CHECK-NEXT: ret i32 [[ABS]]327;328 %t2 = sub i32 %b, %a329 %t1 = sub i32 %a, %b330 %cmp = icmp slt i32 %t1, 1331 %abs = select i1 %cmp, i32 %t1, i32 %t2332 ret i32 %abs333}334 335; The following 5 tests use a shift+add+xor to implement abs():336; B = ashr i8 A, 7 -- smear the sign bit.337; xor (add A, B), B -- add -1 and flip bits if negative338 339define i8 @shifty_abs_commute0(i8 %x) {340; CHECK-LABEL: @shifty_abs_commute0(341; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)342; CHECK-NEXT: ret i8 [[ABS]]343;344 %signbit = ashr i8 %x, 7345 %add = add i8 %signbit, %x346 %abs = xor i8 %add, %signbit347 ret i8 %abs348}349 350define i8 @shifty_abs_commute0_nsw(i8 %x) {351; CHECK-LABEL: @shifty_abs_commute0_nsw(352; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true)353; CHECK-NEXT: ret i8 [[ABS]]354;355 %signbit = ashr i8 %x, 7356 %add = add nsw i8 %signbit, %x357 %abs = xor i8 %add, %signbit358 ret i8 %abs359}360 361; The nuw flag creates a contradiction. If the shift produces all 1s, the only362; way for the add to not wrap is for %x to be 0, but then the shift couldn't363; have produced all 1s. We partially optimize this.364define i8 @shifty_abs_commute0_nuw(i8 %x) {365; CHECK-LABEL: @shifty_abs_commute0_nuw(366; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 0)367; CHECK-NEXT: ret i8 [[ABS]]368;369 %signbit = ashr i8 %x, 7370 %add = add nuw i8 %signbit, %x371 %abs = xor i8 %add, %signbit372 ret i8 %abs373}374 375define <2 x i8> @shifty_abs_commute1(<2 x i8> %x) {376; CHECK-LABEL: @shifty_abs_commute1(377; CHECK-NEXT: [[ABS:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)378; CHECK-NEXT: ret <2 x i8> [[ABS]]379;380 %signbit = ashr <2 x i8> %x, <i8 7, i8 7>381 %add = add <2 x i8> %signbit, %x382 %abs = xor <2 x i8> %signbit, %add383 ret <2 x i8> %abs384}385 386define <2 x i8> @shifty_abs_commute2(<2 x i8> %x) {387; CHECK-LABEL: @shifty_abs_commute2(388; CHECK-NEXT: [[Y:%.*]] = mul <2 x i8> [[X:%.*]], splat (i8 3)389; CHECK-NEXT: [[ABS:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[Y]], i1 false)390; CHECK-NEXT: ret <2 x i8> [[ABS]]391;392 %y = mul <2 x i8> %x, <i8 3, i8 3> ; extra op to thwart complexity-based canonicalization393 %signbit = ashr <2 x i8> %y, <i8 7, i8 7>394 %add = add <2 x i8> %y, %signbit395 %abs = xor <2 x i8> %signbit, %add396 ret <2 x i8> %abs397}398 399define i8 @shifty_abs_commute3(i8 %x) {400; CHECK-LABEL: @shifty_abs_commute3(401; CHECK-NEXT: [[Y:%.*]] = mul i8 [[X:%.*]], 3402; CHECK-NEXT: [[ABS:%.*]] = call i8 @llvm.abs.i8(i8 [[Y]], i1 false)403; CHECK-NEXT: ret i8 [[ABS]]404;405 %y = mul i8 %x, 3 ; extra op to thwart complexity-based canonicalization406 %signbit = ashr i8 %y, 7407 %add = add i8 %y, %signbit408 %abs = xor i8 %add, %signbit409 ret i8 %abs410}411 412; Negative test - don't transform if it would increase instruction count.413 414declare void @extra_use(i8)415declare void @extra_use_i1(i1)416 417define i8 @shifty_abs_too_many_uses(i8 %x) {418; CHECK-LABEL: @shifty_abs_too_many_uses(419; CHECK-NEXT: [[SIGNBIT:%.*]] = ashr i8 [[X:%.*]], 7420; CHECK-NEXT: [[ADD:%.*]] = add i8 [[X]], [[SIGNBIT]]421; CHECK-NEXT: [[ABS:%.*]] = xor i8 [[ADD]], [[SIGNBIT]]422; CHECK-NEXT: call void @extra_use(i8 [[SIGNBIT]])423; CHECK-NEXT: ret i8 [[ABS]]424;425 %signbit = ashr i8 %x, 7426 %add = add i8 %x, %signbit427 %abs = xor i8 %add, %signbit428 call void @extra_use(i8 %signbit)429 ret i8 %abs430}431 432; There's another way to make abs() using shift, xor, and subtract.433; PR36036 - https://bugs.llvm.org/show_bug.cgi?id=36036434 435define i8 @shifty_sub(i8 %x) {436; CHECK-LABEL: @shifty_sub(437; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)438; CHECK-NEXT: ret i8 [[R]]439;440 %sh = ashr i8 %x, 7441 %xor = xor i8 %x, %sh442 %r = sub i8 %xor, %sh443 ret i8 %r444}445 446define i8 @shifty_sub_nsw_commute(i8 %x) {447; CHECK-LABEL: @shifty_sub_nsw_commute(448; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 true)449; CHECK-NEXT: ret i8 [[R]]450;451 %sh = ashr i8 %x, 7452 %xor = xor i8 %sh, %x453 %r = sub nsw i8 %xor, %sh454 ret i8 %r455}456 457define <4 x i32> @shifty_sub_nuw_vec_commute(<4 x i32> %x) {458; CHECK-LABEL: @shifty_sub_nuw_vec_commute(459; CHECK-NEXT: [[R:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[X:%.*]], <4 x i32> zeroinitializer)460; CHECK-NEXT: ret <4 x i32> [[R]]461;462 %sh = ashr <4 x i32> %x, <i32 31, i32 31, i32 31, i32 31>463 %xor = xor <4 x i32> %sh, %x464 %r = sub nuw <4 x i32> %xor, %sh465 ret <4 x i32> %r466}467 468define i12 @shifty_sub_nsw_nuw(i12 %x) {469; CHECK-LABEL: @shifty_sub_nsw_nuw(470; CHECK-NEXT: [[R:%.*]] = call i12 @llvm.smax.i12(i12 [[X:%.*]], i12 0)471; CHECK-NEXT: ret i12 [[R]]472;473 %sh = ashr i12 %x, 11474 %xor = xor i12 %x, %sh475 %r = sub nsw nuw i12 %xor, %sh476 ret i12 %r477}478 479define i8 @negate_abs(i8 %x) {480; CHECK-LABEL: @negate_abs(481; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.abs.i8(i8 [[X:%.*]], i1 false)482; CHECK-NEXT: [[R:%.*]] = sub i8 0, [[S]]483; CHECK-NEXT: ret i8 [[R]]484;485 %n = sub i8 0, %x486 %c = icmp slt i8 %x, 0487 %s = select i1 %c, i8 %n, i8 %x488 %r = sub i8 0, %s489 ret i8 %r490}491 492define <2 x i8> @negate_nabs(<2 x i8> %x) {493; CHECK-LABEL: @negate_nabs(494; CHECK-NEXT: [[TMP1:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[X:%.*]], i1 false)495; CHECK-NEXT: ret <2 x i8> [[TMP1]]496;497 %n = sub <2 x i8> zeroinitializer, %x498 %c = icmp slt <2 x i8> %x, zeroinitializer499 %s = select <2 x i1> %c, <2 x i8> %x, <2 x i8> %n500 %r = sub <2 x i8> zeroinitializer, %s501 ret <2 x i8> %r502}503 504define i1 @abs_must_be_positive(i32 %x) {505; CHECK-LABEL: @abs_must_be_positive(506; CHECK-NEXT: ret i1 true507;508 %negx = sub nsw i32 0, %x509 %c = icmp sge i32 %x, 0510 %sel = select i1 %c, i32 %x, i32 %negx511 %c2 = icmp sge i32 %sel, 0512 ret i1 %c2513}514 515define i8 @abs_swapped(i8 %a) {516; CHECK-LABEL: @abs_swapped(517; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[A:%.*]]518; CHECK-NEXT: call void @extra_use(i8 [[NEG]])519; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.abs.i8(i8 [[A]], i1 false)520; CHECK-NEXT: ret i8 [[M1]]521;522 %neg = sub i8 0, %a523 call void @extra_use(i8 %neg)524 %cmp1 = icmp sgt i8 %a, 0525 %m1 = select i1 %cmp1, i8 %a, i8 %neg526 ret i8 %m1527}528 529define i8 @nabs_swapped(i8 %a) {530; CHECK-LABEL: @nabs_swapped(531; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[A:%.*]]532; CHECK-NEXT: call void @extra_use(i8 [[NEG]])533; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[A]], i1 false)534; CHECK-NEXT: [[M2:%.*]] = sub i8 0, [[TMP1]]535; CHECK-NEXT: ret i8 [[M2]]536;537 %neg = sub i8 0, %a538 call void @extra_use(i8 %neg)539 %cmp2 = icmp sgt i8 %a, 0540 %m2 = select i1 %cmp2, i8 %neg, i8 %a541 ret i8 %m2542}543 544define i8 @abs_different_constants(i8 %a) {545; CHECK-LABEL: @abs_different_constants(546; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[A:%.*]]547; CHECK-NEXT: call void @extra_use(i8 [[NEG]])548; CHECK-NEXT: [[M1:%.*]] = call i8 @llvm.abs.i8(i8 [[A]], i1 false)549; CHECK-NEXT: ret i8 [[M1]]550;551 %neg = sub i8 0, %a552 call void @extra_use(i8 %neg)553 %cmp1 = icmp sgt i8 %a, -1554 %m1 = select i1 %cmp1, i8 %a, i8 %neg555 ret i8 %m1556}557 558define i8 @nabs_different_constants(i8 %a) {559; CHECK-LABEL: @nabs_different_constants(560; CHECK-NEXT: [[NEG:%.*]] = sub i8 0, [[A:%.*]]561; CHECK-NEXT: call void @extra_use(i8 [[NEG]])562; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[A]], i1 false)563; CHECK-NEXT: [[M2:%.*]] = sub i8 0, [[TMP1]]564; CHECK-NEXT: ret i8 [[M2]]565;566 %neg = sub i8 0, %a567 call void @extra_use(i8 %neg)568 %cmp2 = icmp sgt i8 %a, -1569 %m2 = select i1 %cmp2, i8 %neg, i8 %a570 ret i8 %m2571}572 573@g = external global i64574 575; PR45539 - https://bugs.llvm.org/show_bug.cgi?id=45539576 577define i64 @infinite_loop_constant_expression_abs(i64 %arg) {578; CHECK-LABEL: @infinite_loop_constant_expression_abs(579; CHECK-NEXT: [[T:%.*]] = sub i64 ptrtoint (ptr @g to i64), [[ARG:%.*]]580; CHECK-NEXT: [[T3:%.*]] = call i64 @llvm.abs.i64(i64 [[T]], i1 true)581; CHECK-NEXT: ret i64 [[T3]]582;583 %t = sub i64 ptrtoint (ptr @g to i64), %arg584 %t1 = icmp slt i64 %t, 0585 %t2 = sub nsw i64 0, %t586 %t3 = select i1 %t1, i64 %t2, i64 %t587 ret i64 %t3588}589 590define i8 @abs_extra_use_icmp(i8 %x) {591; CHECK-LABEL: @abs_extra_use_icmp(592; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], 0593; CHECK-NEXT: call void @extra_use_i1(i1 [[C]])594; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)595; CHECK-NEXT: ret i8 [[S]]596;597 %c = icmp slt i8 %x, 0598 call void @extra_use_i1(i1 %c)599 %n = sub i8 0, %x600 %s = select i1 %c, i8 %n, i8 %x601 ret i8 %s602}603 604define i8 @abs_extra_use_sub(i8 %x) {605; CHECK-LABEL: @abs_extra_use_sub(606; CHECK-NEXT: [[N:%.*]] = sub i8 0, [[X:%.*]]607; CHECK-NEXT: call void @extra_use(i8 [[N]])608; CHECK-NEXT: [[S:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)609; CHECK-NEXT: ret i8 [[S]]610;611 %c = icmp slt i8 %x, 0612 %n = sub i8 0, %x613 call void @extra_use(i8 %n)614 %s = select i1 %c, i8 %n, i8 %x615 ret i8 %s616}617 618define i8 @abs_extra_use_icmp_sub(i8 %x) {619; CHECK-LABEL: @abs_extra_use_icmp_sub(620; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], 0621; CHECK-NEXT: call void @extra_use_i1(i1 [[C]])622; CHECK-NEXT: [[N:%.*]] = sub i8 0, [[X]]623; CHECK-NEXT: call void @extra_use(i8 [[N]])624; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 [[N]], i8 [[X]]625; CHECK-NEXT: ret i8 [[S]]626;627 %c = icmp slt i8 %x, 0628 call void @extra_use_i1(i1 %c)629 %n = sub i8 0, %x630 call void @extra_use(i8 %n)631 %s = select i1 %c, i8 %n, i8 %x632 ret i8 %s633}634 635define i8 @nabs_extra_use_icmp(i8 %x) {636; CHECK-LABEL: @nabs_extra_use_icmp(637; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], 0638; CHECK-NEXT: call void @extra_use_i1(i1 [[C]])639; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)640; CHECK-NEXT: [[S:%.*]] = sub i8 0, [[TMP1]]641; CHECK-NEXT: ret i8 [[S]]642;643 %c = icmp slt i8 %x, 0644 call void @extra_use_i1(i1 %c)645 %n = sub i8 0, %x646 %s = select i1 %c, i8 %x, i8 %n647 ret i8 %s648}649 650define i8 @nabs_extra_use_sub(i8 %x) {651; CHECK-LABEL: @nabs_extra_use_sub(652; CHECK-NEXT: [[N:%.*]] = sub i8 0, [[X:%.*]]653; CHECK-NEXT: call void @extra_use(i8 [[N]])654; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 false)655; CHECK-NEXT: [[S:%.*]] = sub i8 0, [[TMP1]]656; CHECK-NEXT: ret i8 [[S]]657;658 %c = icmp slt i8 %x, 0659 %n = sub i8 0, %x660 call void @extra_use(i8 %n)661 %s = select i1 %c, i8 %x, i8 %n662 ret i8 %s663}664 665define i8 @nabs_extra_use_icmp_sub(i8 %x) {666; CHECK-LABEL: @nabs_extra_use_icmp_sub(667; CHECK-NEXT: [[C:%.*]] = icmp slt i8 [[X:%.*]], 0668; CHECK-NEXT: call void @extra_use_i1(i1 [[C]])669; CHECK-NEXT: [[N:%.*]] = sub i8 0, [[X]]670; CHECK-NEXT: call void @extra_use(i8 [[N]])671; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i8 [[X]], i8 [[N]]672; CHECK-NEXT: ret i8 [[S]]673;674 %c = icmp slt i8 %x, 0675 call void @extra_use_i1(i1 %c)676 %n = sub i8 0, %x677 call void @extra_use(i8 %n)678 %s = select i1 %c, i8 %x, i8 %n679 ret i8 %s680}681 682; TODO: negate-of-abs-diff683 684define i32 @nabs_diff_signed_slt(i32 %a, i32 %b) {685; CHECK-LABEL: @nabs_diff_signed_slt(686; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]687; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw i32 [[B]], [[A]]688; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i32 [[A]], [[B]]689; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB_AB]], i32 [[SUB_BA]]690; CHECK-NEXT: ret i32 [[COND]]691;692 %cmp = icmp slt i32 %a, %b693 %sub_ba = sub nsw i32 %b, %a694 %sub_ab = sub nsw i32 %a, %b695 %cond = select i1 %cmp, i32 %sub_ab, i32 %sub_ba696 ret i32 %cond697}698 699; TODO: negate-of-abs-diff700 701define <2 x i8> @nabs_diff_signed_sle(<2 x i8> %a, <2 x i8> %b) {702; CHECK-LABEL: @nabs_diff_signed_sle(703; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp sgt <2 x i8> [[A:%.*]], [[B:%.*]]704; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw <2 x i8> [[B]], [[A]]705; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw <2 x i8> [[A]], [[B]]706; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP_NOT]], <2 x i8> [[SUB_BA]], <2 x i8> [[SUB_AB]]707; CHECK-NEXT: ret <2 x i8> [[COND]]708;709 %cmp = icmp sle <2 x i8> %a, %b710 %sub_ba = sub nsw <2 x i8> %b, %a711 %sub_ab = sub nsw <2 x i8> %a, %b712 %cond = select <2 x i1> %cmp, <2 x i8> %sub_ab, <2 x i8> %sub_ba713 ret <2 x i8> %cond714}715 716define i8 @abs_diff_signed_sgt(i8 %a, i8 %b) {717; CHECK-LABEL: @abs_diff_signed_sgt(718; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i8 [[A:%.*]], [[B:%.*]]719; CHECK-NEXT: call void @extra_use(i8 [[SUB_AB]])720; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB_AB]], i1 true)721; CHECK-NEXT: ret i8 [[COND]]722;723 %cmp = icmp sgt i8 %a, %b724 %sub_ba = sub nsw i8 %b, %a725 %sub_ab = sub nsw i8 %a, %b726 call void @extra_use(i8 %sub_ab)727 %cond = select i1 %cmp, i8 %sub_ab, i8 %sub_ba728 ret i8 %cond729}730 731define i8 @abs_diff_signed_sge(i8 %a, i8 %b) {732; CHECK-LABEL: @abs_diff_signed_sge(733; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw i8 [[B:%.*]], [[A:%.*]]734; CHECK-NEXT: call void @extra_use(i8 [[SUB_BA]])735; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i8 [[A]], [[B]]736; CHECK-NEXT: call void @extra_use(i8 [[SUB_AB]])737; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB_AB]], i1 true)738; CHECK-NEXT: ret i8 [[COND]]739;740 %cmp = icmp sge i8 %a, %b741 %sub_ba = sub nsw i8 %b, %a742 call void @extra_use(i8 %sub_ba)743 %sub_ab = sub nsw i8 %a, %b744 call void @extra_use(i8 %sub_ab)745 %cond = select i1 %cmp, i8 %sub_ab, i8 %sub_ba746 ret i8 %cond747}748 749; negative test - need nsw750 751define i32 @abs_diff_signed_slt_no_nsw(i32 %a, i32 %b) {752; CHECK-LABEL: @abs_diff_signed_slt_no_nsw(753; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]754; CHECK-NEXT: [[SUB_BA:%.*]] = sub i32 [[B]], [[A]]755; CHECK-NEXT: [[SUB_AB:%.*]] = sub i32 [[A]], [[B]]756; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB_AB]], i32 [[SUB_BA]]757; CHECK-NEXT: ret i32 [[COND]]758;759 %cmp = icmp slt i32 %a, %b760 %sub_ba = sub i32 %b, %a761 %sub_ab = sub i32 %a, %b762 %cond = select i1 %cmp, i32 %sub_ab, i32 %sub_ba763 ret i32 %cond764}765 766; bonus nuw - it's fine to match the pattern, but nuw can't propagate767 768define i8 @abs_diff_signed_sgt_nsw_nuw(i8 %a, i8 %b) {769; CHECK-LABEL: @abs_diff_signed_sgt_nsw_nuw(770; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i8 [[A:%.*]], [[B:%.*]]771; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB_AB]], i1 true)772; CHECK-NEXT: ret i8 [[COND]]773;774 %cmp = icmp sgt i8 %a, %b775 %sub_ba = sub nsw nuw i8 %b, %a776 %sub_ab = sub nsw nuw i8 %a, %b777 %cond = select i1 %cmp, i8 %sub_ab, i8 %sub_ba778 ret i8 %cond779}780 781; this is absolute diff, but nuw can't propagate and nsw can be set.782 783define i8 @abs_diff_signed_sgt_nuw(i8 %a, i8 %b) {784; CHECK-LABEL: @abs_diff_signed_sgt_nuw(785; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i8 [[A:%.*]], [[B:%.*]]786; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB_AB]], i1 true)787; CHECK-NEXT: ret i8 [[COND]]788;789 %cmp = icmp sgt i8 %a, %b790 %sub_ba = sub nuw i8 %b, %a791 %sub_ab = sub nuw i8 %a, %b792 %cond = select i1 %cmp, i8 %sub_ab, i8 %sub_ba793 ret i8 %cond794}795 796; same as above797 798define i8 @abs_diff_signed_sgt_nuw_extra_use1(i8 %a, i8 %b) {799; CHECK-LABEL: @abs_diff_signed_sgt_nuw_extra_use1(800; CHECK-NEXT: [[SUB_BA:%.*]] = sub nuw i8 [[B:%.*]], [[A:%.*]]801; CHECK-NEXT: call void @extra_use(i8 [[SUB_BA]])802; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i8 [[A]], [[B]]803; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB_AB]], i1 true)804; CHECK-NEXT: ret i8 [[COND]]805;806 %cmp = icmp sgt i8 %a, %b807 %sub_ba = sub nuw i8 %b, %a808 call void @extra_use(i8 %sub_ba)809 %sub_ab = sub nuw i8 %a, %b810 %cond = select i1 %cmp, i8 %sub_ab, i8 %sub_ba811 ret i8 %cond812}813 814; nuw can't propagate, and the extra use prevents applying nsw815 816define i8 @abs_diff_signed_sgt_nuw_extra_use2(i8 %a, i8 %b) {817; CHECK-LABEL: @abs_diff_signed_sgt_nuw_extra_use2(818; CHECK-NEXT: [[SUB_AB:%.*]] = sub i8 [[A:%.*]], [[B:%.*]]819; CHECK-NEXT: call void @extra_use(i8 [[SUB_AB]])820; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB_AB]], i1 true)821; CHECK-NEXT: ret i8 [[COND]]822;823 %cmp = icmp sgt i8 %a, %b824 %sub_ba = sub nuw i8 %b, %a825 %sub_ab = sub nuw i8 %a, %b826 call void @extra_use(i8 %sub_ab)827 %cond = select i1 %cmp, i8 %sub_ab, i8 %sub_ba828 ret i8 %cond829}830 831; same as above832 833define i8 @abs_diff_signed_sgt_nuw_extra_use3(i8 %a, i8 %b) {834; CHECK-LABEL: @abs_diff_signed_sgt_nuw_extra_use3(835; CHECK-NEXT: [[SUB_BA:%.*]] = sub nuw i8 [[B:%.*]], [[A:%.*]]836; CHECK-NEXT: call void @extra_use(i8 [[SUB_BA]])837; CHECK-NEXT: [[SUB_AB:%.*]] = sub i8 [[A]], [[B]]838; CHECK-NEXT: call void @extra_use(i8 [[SUB_AB]])839; CHECK-NEXT: [[COND:%.*]] = call i8 @llvm.abs.i8(i8 [[SUB_AB]], i1 true)840; CHECK-NEXT: ret i8 [[COND]]841;842 %cmp = icmp sgt i8 %a, %b843 %sub_ba = sub nuw i8 %b, %a844 call void @extra_use(i8 %sub_ba)845 %sub_ab = sub nuw i8 %a, %b846 call void @extra_use(i8 %sub_ab)847 %cond = select i1 %cmp, i8 %sub_ab, i8 %sub_ba848 ret i8 %cond849}850 851; negative test - wrong predicate852 853define i32 @abs_diff_signed_slt_swap_wrong_pred1(i32 %a, i32 %b) {854; CHECK-LABEL: @abs_diff_signed_slt_swap_wrong_pred1(855; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i32 [[A:%.*]], [[B:%.*]]856; CHECK-NEXT: ret i32 [[SUB_AB]]857;858 %cmp = icmp eq i32 %a, %b859 %sub_ba = sub nsw i32 %b, %a860 %sub_ab = sub nsw i32 %a, %b861 %cond = select i1 %cmp, i32 %sub_ba, i32 %sub_ab862 ret i32 %cond863}864 865; negative test - wrong predicate866 867define i32 @abs_diff_signed_slt_swap_wrong_pred2(i32 %a, i32 %b) {868; CHECK-LABEL: @abs_diff_signed_slt_swap_wrong_pred2(869; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], [[B:%.*]]870; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw i32 [[B]], [[A]]871; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i32 [[A]], [[B]]872; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB_BA]], i32 [[SUB_AB]]873; CHECK-NEXT: ret i32 [[COND]]874;875 %cmp = icmp ult i32 %a, %b876 %sub_ba = sub nsw i32 %b, %a877 %sub_ab = sub nsw i32 %a, %b878 %cond = select i1 %cmp, i32 %sub_ba, i32 %sub_ab879 ret i32 %cond880}881 882; negative test - need common operands883 884define i32 @abs_diff_signed_slt_swap_wrong_op(i32 %a, i32 %b, i32 %z) {885; CHECK-LABEL: @abs_diff_signed_slt_swap_wrong_op(886; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A:%.*]], [[B:%.*]]887; CHECK-NEXT: [[SUB_BZ:%.*]] = sub nsw i32 [[B]], [[Z:%.*]]888; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i32 [[A]], [[B]]889; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB_BZ]], i32 [[SUB_AB]]890; CHECK-NEXT: ret i32 [[COND]]891;892 %cmp = icmp eq i32 %a, %b893 %sub_bz = sub nsw i32 %b, %z894 %sub_ab = sub nsw i32 %a, %b895 %cond = select i1 %cmp, i32 %sub_bz, i32 %sub_ab896 ret i32 %cond897}898 899define i32 @abs_diff_signed_slt_swap(i32 %a, i32 %b) {900; CHECK-LABEL: @abs_diff_signed_slt_swap(901; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i32 [[A:%.*]], [[B:%.*]]902; CHECK-NEXT: [[COND:%.*]] = call i32 @llvm.abs.i32(i32 [[SUB_AB]], i1 true)903; CHECK-NEXT: ret i32 [[COND]]904;905 %cmp = icmp slt i32 %a, %b906 %sub_ba = sub nsw i32 %b, %a907 %sub_ab = sub nsw i32 %a, %b908 %cond = select i1 %cmp, i32 %sub_ba, i32 %sub_ab909 ret i32 %cond910}911 912define <2 x i8> @abs_diff_signed_sle_swap(<2 x i8> %a, <2 x i8> %b) {913; CHECK-LABEL: @abs_diff_signed_sle_swap(914; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw <2 x i8> [[A:%.*]], [[B:%.*]]915; CHECK-NEXT: [[COND:%.*]] = call <2 x i8> @llvm.abs.v2i8(<2 x i8> [[SUB_AB]], i1 true)916; CHECK-NEXT: ret <2 x i8> [[COND]]917;918 %cmp = icmp sle <2 x i8> %a, %b919 %sub_ba = sub nsw <2 x i8> %b, %a920 %sub_ab = sub nsw <2 x i8> %a, %b921 %cond = select <2 x i1> %cmp, <2 x i8> %sub_ba, <2 x i8> %sub_ab922 ret <2 x i8> %cond923}924 925; TODO: negate-of-abs-diff926 927define i8 @nabs_diff_signed_sgt_swap(i8 %a, i8 %b) {928; CHECK-LABEL: @nabs_diff_signed_sgt_swap(929; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A:%.*]], [[B:%.*]]930; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw i8 [[B]], [[A]]931; CHECK-NEXT: call void @extra_use(i8 [[SUB_BA]])932; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i8 [[A]], [[B]]933; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i8 [[SUB_BA]], i8 [[SUB_AB]]934; CHECK-NEXT: ret i8 [[COND]]935;936 %cmp = icmp sgt i8 %a, %b937 %sub_ba = sub nsw i8 %b, %a938 call void @extra_use(i8 %sub_ba)939 %sub_ab = sub nsw i8 %a, %b940 %cond = select i1 %cmp, i8 %sub_ba, i8 %sub_ab941 ret i8 %cond942}943 944; TODO: negate-of-abs-diff, but too many uses?945 946define i8 @nabs_diff_signed_sge_swap(i8 %a, i8 %b) {947; CHECK-LABEL: @nabs_diff_signed_sge_swap(948; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp slt i8 [[A:%.*]], [[B:%.*]]949; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw i8 [[B]], [[A]]950; CHECK-NEXT: call void @extra_use(i8 [[SUB_BA]])951; CHECK-NEXT: [[SUB_AB:%.*]] = sub nsw i8 [[A]], [[B]]952; CHECK-NEXT: call void @extra_use(i8 [[SUB_AB]])953; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP_NOT]], i8 [[SUB_AB]], i8 [[SUB_BA]]954; CHECK-NEXT: ret i8 [[COND]]955;956 %cmp = icmp sge i8 %a, %b957 %sub_ba = sub nsw i8 %b, %a958 call void @extra_use(i8 %sub_ba)959 %sub_ab = sub nsw i8 %a, %b960 call void @extra_use(i8 %sub_ab)961 %cond = select i1 %cmp, i8 %sub_ba, i8 %sub_ab962 ret i8 %cond963}964 965; negative test - need nsw966 967define i32 @abs_diff_signed_slt_no_nsw_swap(i32 %a, i32 %b) {968; CHECK-LABEL: @abs_diff_signed_slt_no_nsw_swap(969; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A:%.*]], [[B:%.*]]970; CHECK-NEXT: [[SUB_BA:%.*]] = sub nsw i32 [[B]], [[A]]971; CHECK-NEXT: [[SUB_AB:%.*]] = sub i32 [[A]], [[B]]972; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[SUB_BA]], i32 [[SUB_AB]]973; CHECK-NEXT: ret i32 [[COND]]974;975 %cmp = icmp slt i32 %a, %b976 %sub_ba = sub nsw i32 %b, %a977 %sub_ab = sub i32 %a, %b978 %cond = select i1 %cmp, i32 %sub_ba, i32 %sub_ab979 ret i32 %cond980}981 982define <2 x i32> @abs_unary_shuffle_ops(<2 x i32> %x) {983; CHECK-LABEL: @abs_unary_shuffle_ops(984; CHECK-NEXT: [[R2:%.*]] = call <2 x i32> @llvm.abs.v2i32(<2 x i32> [[R1:%.*]], i1 false)985; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x i32> [[R2]], <2 x i32> poison, <2 x i32> <i32 1, i32 0>986; CHECK-NEXT: ret <2 x i32> [[R]]987;988 %a = shufflevector <2 x i32> %x, <2 x i32> poison, <2 x i32> <i32 1, i32 0>989 %r = call <2 x i32> @llvm.abs(<2 x i32> %a, i1 false)990 ret <2 x i32> %r991}992