From c2ebad8d55bd90ac921b1219b25c1d1a864655ff Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Tue, 30 Mar 2021 14:33:30 -0400 Subject: [PATCH] [InstCombine] add fold for demand of low bit of abs() This is one problem shown in https://llvm.org/PR49763 https://alive2.llvm.org/ce/z/cV6-4K https://alive2.llvm.org/ce/z/9_3g-L --- .../InstCombine/InstCombineSimplifyDemanded.cpp | 5 +++++ llvm/test/Transforms/InstCombine/abs-intrinsic.ll | 12 ++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp index 16efe863779a3c..54ca2c10dd047b 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -734,6 +734,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, bool KnownBitsComputed = false; if (IntrinsicInst *II = dyn_cast(I)) { switch (II->getIntrinsicID()) { + case Intrinsic::abs: { + if (DemandedMask == 1) + return II->getArgOperand(0); + break; + } case Intrinsic::bswap: { // If the only bits demanded come from one byte of the bswap result, // just shift the input byte into position to eliminate the bswap. diff --git a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll index a8ee1a9fccacf2..9961c7170d0acf 100644 --- a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll +++ b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll @@ -352,10 +352,11 @@ define <4 x i8> @trunc_abs_sext_vec(<4 x i8> %x) { ret <4 x i8> %t } +; abs() doesn't change the low bit. + define i32 @demand_low_bit(i32 %x) { ; CHECK-LABEL: @demand_low_bit( -; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false) -; CHECK-NEXT: [[R:%.*]] = and i32 [[A]], 1 +; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], 1 ; CHECK-NEXT: ret i32 [[R]] ; %a = call i32 @llvm.abs.i32(i32 %x, i1 false) @@ -363,10 +364,11 @@ define i32 @demand_low_bit(i32 %x) { ret i32 %r } +; Int min behavior doesn't affect the transform. + define <3 x i82> @demand_low_bit_int_min_is_poison(<3 x i82> %x) { ; CHECK-LABEL: @demand_low_bit_int_min_is_poison( -; CHECK-NEXT: [[A:%.*]] = call <3 x i82> @llvm.abs.v3i82(<3 x i82> [[X:%.*]], i1 true) -; CHECK-NEXT: [[R:%.*]] = shl <3 x i82> [[A]], +; CHECK-NEXT: [[R:%.*]] = shl <3 x i82> [[X:%.*]], ; CHECK-NEXT: ret <3 x i82> [[R]] ; %a = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %x, i1 true) @@ -374,6 +376,8 @@ define <3 x i82> @demand_low_bit_int_min_is_poison(<3 x i82> %x) { ret <3 x i82> %r } +; Negative test - only low bit is allowed. + define i32 @demand_low_bits(i32 %x) { ; CHECK-LABEL: @demand_low_bits( ; CHECK-NEXT: [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)