Skip to content

Commit 4c7834e

Browse files
committed
[DAG] computeKnownBits - abs(x) will be zero in the upper bits if x is sign-extended
As reported on #94344 - if x has more than one signbit, then the upper bits of its absolute value are guaranteed to be zero Alive2: https://alive2.llvm.org/ce/z/a87fHU
1 parent be559fe commit 4c7834e

File tree

2 files changed

+13
-42
lines changed

2 files changed

+13
-42
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4051,6 +4051,8 @@ KnownBits SelectionDAG::computeKnownBits(SDValue Op, const APInt &DemandedElts,
40514051
case ISD::ABS: {
40524052
Known2 = computeKnownBits(Op.getOperand(0), DemandedElts, Depth + 1);
40534053
Known = Known2.abs();
4054+
Known.Zero.setHighBits(
4055+
ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1) - 1);
40544056
break;
40554057
}
40564058
case ISD::USUBSAT: {

llvm/test/CodeGen/X86/combine-abs.ll

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,11 @@ define <8 x i32> @combine_v8i32_abs_pos(<8 x i32> %a) {
201201
ret <8 x i32> %2
202202
}
203203

204-
; TODO: (abs x) upper bits are known zero if x has extra sign bits
204+
; (abs x) upper bits are known zero if x has extra sign bits
205205
define i32 @combine_i32_abs_zerosign(i32 %a) {
206206
; CHECK-LABEL: combine_i32_abs_zerosign:
207207
; CHECK: # %bb.0:
208-
; CHECK-NEXT: sarl $15, %edi
209-
; CHECK-NEXT: movl %edi, %eax
210-
; CHECK-NEXT: negl %eax
211-
; CHECK-NEXT: cmovsl %edi, %eax
212-
; CHECK-NEXT: andl $-524288, %eax # imm = 0xFFF80000
208+
; CHECK-NEXT: xorl %eax, %eax
213209
; CHECK-NEXT: retq
214210
%1 = ashr i32 %a, 15
215211
%2 = call i32 @llvm.abs.i32(i32 %1, i1 false)
@@ -218,42 +214,15 @@ define i32 @combine_i32_abs_zerosign(i32 %a) {
218214
}
219215

220216
define <8 x i16> @combine_v8i16_abs_zerosign(<8 x i16> %a) {
221-
; SSE2-LABEL: combine_v8i16_abs_zerosign:
222-
; SSE2: # %bb.0:
223-
; SSE2-NEXT: pmulhw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
224-
; SSE2-NEXT: pxor %xmm1, %xmm1
225-
; SSE2-NEXT: psubw %xmm0, %xmm1
226-
; SSE2-NEXT: pand %xmm1, %xmm0
227-
; SSE2-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
228-
; SSE2-NEXT: retq
229-
;
230-
; SSE42-LABEL: combine_v8i16_abs_zerosign:
231-
; SSE42: # %bb.0:
232-
; SSE42-NEXT: pmulhw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
233-
; SSE42-NEXT: pabsw %xmm0, %xmm0
234-
; SSE42-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
235-
; SSE42-NEXT: retq
236-
;
237-
; AVX2-LABEL: combine_v8i16_abs_zerosign:
238-
; AVX2: # %bb.0:
239-
; AVX2-NEXT: vpmulhw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
240-
; AVX2-NEXT: vpabsw %xmm0, %xmm0
241-
; AVX2-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
242-
; AVX2-NEXT: retq
243-
;
244-
; AVX512F-LABEL: combine_v8i16_abs_zerosign:
245-
; AVX512F: # %bb.0:
246-
; AVX512F-NEXT: vpmulhw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
247-
; AVX512F-NEXT: vpabsw %xmm0, %xmm0
248-
; AVX512F-NEXT: vpand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
249-
; AVX512F-NEXT: retq
217+
; SSE-LABEL: combine_v8i16_abs_zerosign:
218+
; SSE: # %bb.0:
219+
; SSE-NEXT: xorps %xmm0, %xmm0
220+
; SSE-NEXT: retq
250221
;
251-
; AVX512VL-LABEL: combine_v8i16_abs_zerosign:
252-
; AVX512VL: # %bb.0:
253-
; AVX512VL-NEXT: vpmulhw {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
254-
; AVX512VL-NEXT: vpabsw %xmm0, %xmm0
255-
; AVX512VL-NEXT: vpandd {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm0, %xmm0
256-
; AVX512VL-NEXT: retq
222+
; AVX-LABEL: combine_v8i16_abs_zerosign:
223+
; AVX: # %bb.0:
224+
; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0
225+
; AVX-NEXT: retq
257226
%1 = ashr <8 x i16> %a, <i16 7, i16 8, i16 9, i16 10, i16 11, i16 12, i16 13, i16 14>
258227
%2 = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %1, i1 false)
259228
%3 = and <8 x i16> %2, <i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768, i16 32768>
@@ -268,7 +237,7 @@ define i32 @combine_i32_abs_zerosign_negative(i32 %a) {
268237
; CHECK-NEXT: movl %edi, %eax
269238
; CHECK-NEXT: negl %eax
270239
; CHECK-NEXT: cmovsl %edi, %eax
271-
; CHECK-NEXT: andl $-524288, %eax # imm = 0xFFF80000
240+
; CHECK-NEXT: andl $536346624, %eax # imm = 0x1FF80000
272241
; CHECK-NEXT: retq
273242
%1 = ashr i32 %a, 3
274243
%2 = call i32 @llvm.abs.i32(i32 %1, i1 false)

0 commit comments

Comments
 (0)