Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25203,6 +25203,29 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
return DAG.getNode(ISD::SPLAT_VECTOR, SDLoc(N), VT, V);
}

// build_vector(build_pair(x,y)) -> bitcast(build_pair(x,y))
if (N->getNumOperands() == 1 &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forgot 1 element build_vector is even valid

N->getOperand(0).getOpcode() == ISD::BUILD_PAIR)
return DAG.getBitcast(VT, N->getOperand(0));

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised you get away without any legality checks

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BUILD_PAIR nodes get legalized away pretty early

// build_vector(build_pair(x,y),build_pair(z,w),...)
// --> bitcast(build_vector(x,y,z,w,...))
if (VT.isInteger() && !cast<BuildVectorSDNode>(N)->getSplatValue() &&
all_of(N->ops(),
[](SDValue Op) { return Op.getOpcode() == ISD::BUILD_PAIR; })) {
EVT PairSVT = N->getOperand(0).getOperand(0).getValueType();
EVT PairVT = EVT::getVectorVT(*DAG.getContext(), PairSVT,
VT.getVectorElementCount() * 2);
unsigned Lo = DAG.getDataLayout().isBigEndian() ? 1 : 0;
unsigned Hi = 1 - Lo;
SmallVector<SDValue, 4> PairOps;
for (SDValue Op : N->ops()) {
PairOps.push_back(Op.getOperand(Lo));
PairOps.push_back(Op.getOperand(Hi));
}
return DAG.getBitcast(VT, DAG.getBuildVector(PairVT, SDLoc(N), PairOps));
}

return SDValue();
}

Expand Down
279 changes: 207 additions & 72 deletions llvm/test/CodeGen/AArch64/andorxor.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1319,10 +1319,20 @@ entry:
define <2 x i128> @and_v2i128(<2 x i128> %d, <2 x i128> %e) {
; CHECK-SD-LABEL: and_v2i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: and x2, x2, x6
; CHECK-SD-NEXT: and x0, x0, x4
; CHECK-SD-NEXT: and x1, x1, x5
; CHECK-SD-NEXT: and x3, x3, x7
; CHECK-SD-NEXT: fmov d0, x4
; CHECK-SD-NEXT: fmov d1, x0
; CHECK-SD-NEXT: fmov d2, x6
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: mov v0.d[1], x5
; CHECK-SD-NEXT: mov v1.d[1], x1
; CHECK-SD-NEXT: mov v2.d[1], x7
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: and v0.16b, v1.16b, v0.16b
; CHECK-SD-NEXT: and v2.16b, v3.16b, v2.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v2.d[1]
; CHECK-SD-NEXT: fmov x2, d2
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: and_v2i128:
Expand All @@ -1340,10 +1350,20 @@ entry:
define <2 x i128> @or_v2i128(<2 x i128> %d, <2 x i128> %e) {
; CHECK-SD-LABEL: or_v2i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: orr x2, x2, x6
; CHECK-SD-NEXT: orr x0, x0, x4
; CHECK-SD-NEXT: orr x1, x1, x5
; CHECK-SD-NEXT: orr x3, x3, x7
; CHECK-SD-NEXT: fmov d0, x4
; CHECK-SD-NEXT: fmov d1, x0
; CHECK-SD-NEXT: fmov d2, x6
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: mov v0.d[1], x5
; CHECK-SD-NEXT: mov v1.d[1], x1
; CHECK-SD-NEXT: mov v2.d[1], x7
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-SD-NEXT: orr v2.16b, v3.16b, v2.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v2.d[1]
; CHECK-SD-NEXT: fmov x2, d2
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: or_v2i128:
Expand All @@ -1361,10 +1381,20 @@ entry:
define <2 x i128> @xor_v2i128(<2 x i128> %d, <2 x i128> %e) {
; CHECK-SD-LABEL: xor_v2i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: eor x2, x2, x6
; CHECK-SD-NEXT: eor x0, x0, x4
; CHECK-SD-NEXT: eor x1, x1, x5
; CHECK-SD-NEXT: eor x3, x3, x7
; CHECK-SD-NEXT: fmov d0, x4
; CHECK-SD-NEXT: fmov d1, x0
; CHECK-SD-NEXT: fmov d2, x6
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: mov v0.d[1], x5
; CHECK-SD-NEXT: mov v1.d[1], x1
; CHECK-SD-NEXT: mov v2.d[1], x7
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: eor v0.16b, v1.16b, v0.16b
; CHECK-SD-NEXT: eor v2.16b, v3.16b, v2.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v2.d[1]
; CHECK-SD-NEXT: fmov x2, d2
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: xor_v2i128:
Expand All @@ -1382,14 +1412,29 @@ entry:
define <3 x i128> @and_v3i128(<3 x i128> %d, <3 x i128> %e) {
; CHECK-SD-LABEL: and_v3i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: ldp x8, x9, [sp]
; CHECK-SD-NEXT: and x0, x0, x6
; CHECK-SD-NEXT: ldp x11, x10, [sp, #16]
; CHECK-SD-NEXT: and x1, x1, x7
; CHECK-SD-NEXT: and x2, x2, x8
; CHECK-SD-NEXT: and x3, x3, x9
; CHECK-SD-NEXT: and x4, x4, x11
; CHECK-SD-NEXT: and x5, x5, x10
; CHECK-SD-NEXT: fmov d0, x6
; CHECK-SD-NEXT: fmov d1, x0
; CHECK-SD-NEXT: ldr d2, [sp]
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: fmov d5, x4
; CHECK-SD-NEXT: ldr d4, [sp, #16]
; CHECK-SD-NEXT: add x8, sp, #8
; CHECK-SD-NEXT: add x9, sp, #24
; CHECK-SD-NEXT: mov v0.d[1], x7
; CHECK-SD-NEXT: mov v1.d[1], x1
; CHECK-SD-NEXT: ld1 { v2.d }[1], [x8]
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: mov v5.d[1], x5
; CHECK-SD-NEXT: ld1 { v4.d }[1], [x9]
; CHECK-SD-NEXT: and v0.16b, v1.16b, v0.16b
; CHECK-SD-NEXT: and v1.16b, v5.16b, v4.16b
; CHECK-SD-NEXT: and v2.16b, v3.16b, v2.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v2.d[1]
; CHECK-SD-NEXT: mov x5, v1.d[1]
; CHECK-SD-NEXT: fmov x2, d2
; CHECK-SD-NEXT: fmov x4, d1
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: and_v3i128:
Expand All @@ -1411,14 +1456,29 @@ entry:
define <3 x i128> @or_v3i128(<3 x i128> %d, <3 x i128> %e) {
; CHECK-SD-LABEL: or_v3i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: ldp x8, x9, [sp]
; CHECK-SD-NEXT: orr x0, x0, x6
; CHECK-SD-NEXT: ldp x11, x10, [sp, #16]
; CHECK-SD-NEXT: orr x1, x1, x7
; CHECK-SD-NEXT: orr x2, x2, x8
; CHECK-SD-NEXT: orr x3, x3, x9
; CHECK-SD-NEXT: orr x4, x4, x11
; CHECK-SD-NEXT: orr x5, x5, x10
; CHECK-SD-NEXT: fmov d0, x6
; CHECK-SD-NEXT: fmov d1, x0
; CHECK-SD-NEXT: ldr d2, [sp]
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: fmov d5, x4
; CHECK-SD-NEXT: ldr d4, [sp, #16]
; CHECK-SD-NEXT: add x8, sp, #8
; CHECK-SD-NEXT: add x9, sp, #24
; CHECK-SD-NEXT: mov v0.d[1], x7
; CHECK-SD-NEXT: mov v1.d[1], x1
; CHECK-SD-NEXT: ld1 { v2.d }[1], [x8]
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: mov v5.d[1], x5
; CHECK-SD-NEXT: ld1 { v4.d }[1], [x9]
; CHECK-SD-NEXT: orr v0.16b, v1.16b, v0.16b
; CHECK-SD-NEXT: orr v1.16b, v5.16b, v4.16b
; CHECK-SD-NEXT: orr v2.16b, v3.16b, v2.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v2.d[1]
; CHECK-SD-NEXT: mov x5, v1.d[1]
; CHECK-SD-NEXT: fmov x2, d2
; CHECK-SD-NEXT: fmov x4, d1
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: or_v3i128:
Expand All @@ -1440,14 +1500,29 @@ entry:
define <3 x i128> @xor_v3i128(<3 x i128> %d, <3 x i128> %e) {
; CHECK-SD-LABEL: xor_v3i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: ldp x8, x9, [sp]
; CHECK-SD-NEXT: eor x0, x0, x6
; CHECK-SD-NEXT: ldp x11, x10, [sp, #16]
; CHECK-SD-NEXT: eor x1, x1, x7
; CHECK-SD-NEXT: eor x2, x2, x8
; CHECK-SD-NEXT: eor x3, x3, x9
; CHECK-SD-NEXT: eor x4, x4, x11
; CHECK-SD-NEXT: eor x5, x5, x10
; CHECK-SD-NEXT: fmov d0, x6
; CHECK-SD-NEXT: fmov d1, x0
; CHECK-SD-NEXT: ldr d2, [sp]
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: fmov d5, x4
; CHECK-SD-NEXT: ldr d4, [sp, #16]
; CHECK-SD-NEXT: add x8, sp, #8
; CHECK-SD-NEXT: add x9, sp, #24
; CHECK-SD-NEXT: mov v0.d[1], x7
; CHECK-SD-NEXT: mov v1.d[1], x1
; CHECK-SD-NEXT: ld1 { v2.d }[1], [x8]
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: mov v5.d[1], x5
; CHECK-SD-NEXT: ld1 { v4.d }[1], [x9]
; CHECK-SD-NEXT: eor v0.16b, v1.16b, v0.16b
; CHECK-SD-NEXT: eor v1.16b, v5.16b, v4.16b
; CHECK-SD-NEXT: eor v2.16b, v3.16b, v2.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v2.d[1]
; CHECK-SD-NEXT: mov x5, v1.d[1]
; CHECK-SD-NEXT: fmov x2, d2
; CHECK-SD-NEXT: fmov x4, d1
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: xor_v3i128:
Expand All @@ -1469,18 +1544,38 @@ entry:
define <4 x i128> @and_v4i128(<4 x i128> %d, <4 x i128> %e) {
; CHECK-SD-LABEL: and_v4i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: ldp x9, x8, [sp, #32]
; CHECK-SD-NEXT: ldp x11, x10, [sp]
; CHECK-SD-NEXT: ldp x13, x12, [sp, #16]
; CHECK-SD-NEXT: ldp x15, x14, [sp, #48]
; CHECK-SD-NEXT: and x4, x4, x9
; CHECK-SD-NEXT: and x0, x0, x11
; CHECK-SD-NEXT: and x1, x1, x10
; CHECK-SD-NEXT: and x5, x5, x8
; CHECK-SD-NEXT: and x2, x2, x13
; CHECK-SD-NEXT: and x3, x3, x12
; CHECK-SD-NEXT: and x6, x6, x15
; CHECK-SD-NEXT: and x7, x7, x14
; CHECK-SD-NEXT: ldr d0, [sp]
; CHECK-SD-NEXT: fmov d2, x0
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: fmov d5, x4
; CHECK-SD-NEXT: fmov d7, x6
; CHECK-SD-NEXT: add x8, sp, #8
; CHECK-SD-NEXT: ldr d1, [sp, #16]
; CHECK-SD-NEXT: ld1 { v0.d }[1], [x8]
; CHECK-SD-NEXT: add x8, sp, #24
; CHECK-SD-NEXT: ldr d4, [sp, #32]
; CHECK-SD-NEXT: ldr d6, [sp, #48]
; CHECK-SD-NEXT: mov v2.d[1], x1
; CHECK-SD-NEXT: ld1 { v1.d }[1], [x8]
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: add x8, sp, #40
; CHECK-SD-NEXT: mov v5.d[1], x5
; CHECK-SD-NEXT: add x9, sp, #56
; CHECK-SD-NEXT: mov v7.d[1], x7
; CHECK-SD-NEXT: ld1 { v4.d }[1], [x8]
; CHECK-SD-NEXT: ld1 { v6.d }[1], [x9]
; CHECK-SD-NEXT: and v0.16b, v2.16b, v0.16b
; CHECK-SD-NEXT: and v1.16b, v3.16b, v1.16b
; CHECK-SD-NEXT: and v2.16b, v7.16b, v6.16b
; CHECK-SD-NEXT: and v3.16b, v5.16b, v4.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v1.d[1]
; CHECK-SD-NEXT: fmov x2, d1
; CHECK-SD-NEXT: mov x5, v3.d[1]
; CHECK-SD-NEXT: mov x7, v2.d[1]
; CHECK-SD-NEXT: fmov x4, d3
; CHECK-SD-NEXT: fmov x6, d2
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: and_v4i128:
Expand All @@ -1506,18 +1601,38 @@ entry:
define <4 x i128> @or_v4i128(<4 x i128> %d, <4 x i128> %e) {
; CHECK-SD-LABEL: or_v4i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: ldp x9, x8, [sp, #32]
; CHECK-SD-NEXT: ldp x11, x10, [sp]
; CHECK-SD-NEXT: ldp x13, x12, [sp, #16]
; CHECK-SD-NEXT: ldp x15, x14, [sp, #48]
; CHECK-SD-NEXT: orr x4, x4, x9
; CHECK-SD-NEXT: orr x0, x0, x11
; CHECK-SD-NEXT: orr x1, x1, x10
; CHECK-SD-NEXT: orr x5, x5, x8
; CHECK-SD-NEXT: orr x2, x2, x13
; CHECK-SD-NEXT: orr x3, x3, x12
; CHECK-SD-NEXT: orr x6, x6, x15
; CHECK-SD-NEXT: orr x7, x7, x14
; CHECK-SD-NEXT: ldr d0, [sp]
; CHECK-SD-NEXT: fmov d2, x0
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: fmov d5, x4
; CHECK-SD-NEXT: fmov d7, x6
; CHECK-SD-NEXT: add x8, sp, #8
; CHECK-SD-NEXT: ldr d1, [sp, #16]
; CHECK-SD-NEXT: ld1 { v0.d }[1], [x8]
; CHECK-SD-NEXT: add x8, sp, #24
; CHECK-SD-NEXT: ldr d4, [sp, #32]
; CHECK-SD-NEXT: ldr d6, [sp, #48]
; CHECK-SD-NEXT: mov v2.d[1], x1
; CHECK-SD-NEXT: ld1 { v1.d }[1], [x8]
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: add x8, sp, #40
; CHECK-SD-NEXT: mov v5.d[1], x5
; CHECK-SD-NEXT: add x9, sp, #56
; CHECK-SD-NEXT: mov v7.d[1], x7
; CHECK-SD-NEXT: ld1 { v4.d }[1], [x8]
; CHECK-SD-NEXT: ld1 { v6.d }[1], [x9]
; CHECK-SD-NEXT: orr v0.16b, v2.16b, v0.16b
; CHECK-SD-NEXT: orr v1.16b, v3.16b, v1.16b
; CHECK-SD-NEXT: orr v2.16b, v7.16b, v6.16b
; CHECK-SD-NEXT: orr v3.16b, v5.16b, v4.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v1.d[1]
; CHECK-SD-NEXT: fmov x2, d1
; CHECK-SD-NEXT: mov x5, v3.d[1]
; CHECK-SD-NEXT: mov x7, v2.d[1]
; CHECK-SD-NEXT: fmov x4, d3
; CHECK-SD-NEXT: fmov x6, d2
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: or_v4i128:
Expand All @@ -1543,18 +1658,38 @@ entry:
define <4 x i128> @xor_v4i128(<4 x i128> %d, <4 x i128> %e) {
; CHECK-SD-LABEL: xor_v4i128:
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: ldp x9, x8, [sp, #32]
; CHECK-SD-NEXT: ldp x11, x10, [sp]
; CHECK-SD-NEXT: ldp x13, x12, [sp, #16]
; CHECK-SD-NEXT: ldp x15, x14, [sp, #48]
; CHECK-SD-NEXT: eor x4, x4, x9
; CHECK-SD-NEXT: eor x0, x0, x11
; CHECK-SD-NEXT: eor x1, x1, x10
; CHECK-SD-NEXT: eor x5, x5, x8
; CHECK-SD-NEXT: eor x2, x2, x13
; CHECK-SD-NEXT: eor x3, x3, x12
; CHECK-SD-NEXT: eor x6, x6, x15
; CHECK-SD-NEXT: eor x7, x7, x14
; CHECK-SD-NEXT: ldr d0, [sp]
; CHECK-SD-NEXT: fmov d2, x0
; CHECK-SD-NEXT: fmov d3, x2
; CHECK-SD-NEXT: fmov d5, x4
; CHECK-SD-NEXT: fmov d7, x6
; CHECK-SD-NEXT: add x8, sp, #8
; CHECK-SD-NEXT: ldr d1, [sp, #16]
; CHECK-SD-NEXT: ld1 { v0.d }[1], [x8]
; CHECK-SD-NEXT: add x8, sp, #24
; CHECK-SD-NEXT: ldr d4, [sp, #32]
; CHECK-SD-NEXT: ldr d6, [sp, #48]
; CHECK-SD-NEXT: mov v2.d[1], x1
; CHECK-SD-NEXT: ld1 { v1.d }[1], [x8]
; CHECK-SD-NEXT: mov v3.d[1], x3
; CHECK-SD-NEXT: add x8, sp, #40
; CHECK-SD-NEXT: mov v5.d[1], x5
; CHECK-SD-NEXT: add x9, sp, #56
; CHECK-SD-NEXT: mov v7.d[1], x7
; CHECK-SD-NEXT: ld1 { v4.d }[1], [x8]
; CHECK-SD-NEXT: ld1 { v6.d }[1], [x9]
; CHECK-SD-NEXT: eor v0.16b, v2.16b, v0.16b
; CHECK-SD-NEXT: eor v1.16b, v3.16b, v1.16b
; CHECK-SD-NEXT: eor v2.16b, v7.16b, v6.16b
; CHECK-SD-NEXT: eor v3.16b, v5.16b, v4.16b
; CHECK-SD-NEXT: mov x1, v0.d[1]
; CHECK-SD-NEXT: fmov x0, d0
; CHECK-SD-NEXT: mov x3, v1.d[1]
; CHECK-SD-NEXT: fmov x2, d1
; CHECK-SD-NEXT: mov x5, v3.d[1]
; CHECK-SD-NEXT: mov x7, v2.d[1]
; CHECK-SD-NEXT: fmov x4, d3
; CHECK-SD-NEXT: fmov x6, d2
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: xor_v4i128:
Expand Down
Loading