Skip to content

Commit 205a10c

Browse files
committed
[DAG] FoldConstantArithmetic - allow binop folding to work with differing bitcasted constants
We currently only constant fold binop(bitcast(c1),bitcast(c2)) if c1 and c2 are both bitcasted and from the same type. This patch relaxes this assumption to allow the constant build vector to originate from different types (and allow cases where only one operand was bitcasted). We still ensure we bitcast back to one of the original types if both operand were bitcasted (we assume that if we have a non-bitcasted constant then its legal to keep using that type).
1 parent 32b7043 commit 205a10c

File tree

3 files changed

+25
-21
lines changed

3 files changed

+25
-21
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6551,17 +6551,17 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
65516551

65526552
ElementCount NumElts = VT.getVectorElementCount();
65536553

6554-
// See if we can fold through bitcasted integer ops.
6554+
// See if we can fold through any bitcasted integer ops.
65556555
if (NumOps == 2 && VT.isFixedLengthVector() && VT.isInteger() &&
65566556
Ops[0].getValueType() == VT && Ops[1].getValueType() == VT &&
6557-
Ops[0].getOpcode() == ISD::BITCAST &&
6558-
Ops[1].getOpcode() == ISD::BITCAST) {
6557+
(Ops[0].getOpcode() == ISD::BITCAST ||
6558+
Ops[1].getOpcode() == ISD::BITCAST)) {
65596559
SDValue N1 = peekThroughBitcasts(Ops[0]);
65606560
SDValue N2 = peekThroughBitcasts(Ops[1]);
65616561
auto *BV1 = dyn_cast<BuildVectorSDNode>(N1);
65626562
auto *BV2 = dyn_cast<BuildVectorSDNode>(N2);
6563-
EVT BVVT = N1.getValueType();
6564-
if (BV1 && BV2 && BVVT.isInteger() && BVVT == N2.getValueType()) {
6563+
if (BV1 && BV2 && N1.getValueType().isInteger() &&
6564+
N2.getValueType().isInteger()) {
65656565
bool IsLE = getDataLayout().isLittleEndian();
65666566
unsigned EltBits = VT.getScalarSizeInBits();
65676567
SmallVector<APInt> RawBits1, RawBits2;
@@ -6577,15 +6577,22 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
65776577
RawBits.push_back(*Fold);
65786578
}
65796579
if (RawBits.size() == NumElts.getFixedValue()) {
6580-
// We have constant folded, but we need to cast this again back to
6581-
// the original (possibly legalized) type.
6580+
// We have constant folded, but we might need to cast this again back
6581+
// to the original (possibly legalized) type.
6582+
EVT BVVT, BVEltVT;
6583+
if (N1.getValueType() == VT) {
6584+
BVVT = N1.getValueType();
6585+
BVEltVT = BV1->getOperand(0).getValueType();
6586+
} else {
6587+
BVVT = N2.getValueType();
6588+
BVEltVT = BV2->getOperand(0).getValueType();
6589+
}
6590+
unsigned BVEltBits = BVEltVT.getSizeInBits();
65826591
SmallVector<APInt> DstBits;
65836592
BitVector DstUndefs;
65846593
BuildVectorSDNode::recastRawBits(IsLE, BVVT.getScalarSizeInBits(),
65856594
DstBits, RawBits, DstUndefs,
65866595
BitVector(RawBits.size(), false));
6587-
EVT BVEltVT = BV1->getOperand(0).getValueType();
6588-
unsigned BVEltBits = BVEltVT.getSizeInBits();
65896596
SmallVector<SDValue> Ops(DstBits.size(), getUNDEF(BVEltVT));
65906597
for (unsigned I = 0, E = DstBits.size(); I != E; ++I) {
65916598
if (DstUndefs[I])

llvm/test/CodeGen/ARM/vector-store.ll

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -617,17 +617,14 @@ define void @v3i8store(ptr %p) {
617617
; CHECK-LE: @ %bb.0:
618618
; CHECK-LE-NEXT: .pad #4
619619
; CHECK-LE-NEXT: sub sp, #4
620-
; CHECK-LE-NEXT: vmov.i32 d16, #0xff
621-
; CHECK-LE-NEXT: mov r1, sp
622-
; CHECK-LE-NEXT: vmov.i32 d17, #0x0
623-
; CHECK-LE-NEXT: movs r2, #0
624-
; CHECK-LE-NEXT: vand d16, d17, d16
625-
; CHECK-LE-NEXT: vst1.32 {d16[0]}, [r1:32]
626-
; CHECK-LE-NEXT: vld1.32 {d16[0]}, [r1:32]
620+
; CHECK-LE-NEXT: movs r1, #0
621+
; CHECK-LE-NEXT: mov r2, sp
622+
; CHECK-LE-NEXT: str r1, [sp]
623+
; CHECK-LE-NEXT: vld1.32 {d16[0]}, [r2:32]
624+
; CHECK-LE-NEXT: strb r1, [r0, #2]
627625
; CHECK-LE-NEXT: vmovl.u16 q8, d16
628-
; CHECK-LE-NEXT: strb r2, [r0, #2]
629-
; CHECK-LE-NEXT: vmov.32 r1, d16[0]
630-
; CHECK-LE-NEXT: strh r1, [r0]
626+
; CHECK-LE-NEXT: vmov.32 r2, d16[0]
627+
; CHECK-LE-NEXT: strh r2, [r0]
631628
; CHECK-LE-NEXT: add sp, #4
632629
; CHECK-LE-NEXT: bx lr
633630
;

llvm/test/CodeGen/X86/vshift-6.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ define <16 x i8> @do_not_crash(ptr, ptr, ptr, i32, i64, i8) {
3232
; X86-NEXT: movb %al, (%ecx)
3333
; X86-NEXT: movd %eax, %xmm1
3434
; X86-NEXT: psllq $56, %xmm1
35-
; X86-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
3635
; X86-NEXT: pcmpeqd %xmm3, %xmm3
3736
; X86-NEXT: psllw $5, %xmm1
37+
; X86-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}, %xmm1
3838
; X86-NEXT: pxor %xmm2, %xmm2
3939
; X86-NEXT: pxor %xmm0, %xmm0
4040
; X86-NEXT: pcmpgtb %xmm1, %xmm0
@@ -64,9 +64,9 @@ define <16 x i8> @do_not_crash(ptr, ptr, ptr, i32, i64, i8) {
6464
; X64-NEXT: movb %r9b, (%rdi)
6565
; X64-NEXT: movd %r9d, %xmm1
6666
; X64-NEXT: psllq $56, %xmm1
67-
; X64-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
6867
; X64-NEXT: pcmpeqd %xmm2, %xmm2
6968
; X64-NEXT: psllw $5, %xmm1
69+
; X64-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
7070
; X64-NEXT: pxor %xmm3, %xmm3
7171
; X64-NEXT: pxor %xmm0, %xmm0
7272
; X64-NEXT: pcmpgtb %xmm1, %xmm0

0 commit comments

Comments
 (0)