brintos

brintos / llvm-project-archived public Read only

0
0
Text · 31.1 KiB · fd67fc3 Raw
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