Skip to content

Commit 3f81841

Browse files
committed
[AArch64] Add Extract(DUP(C)) as a canonical constant.
As a followup to D128144, this adds extract(DUP(C)) as a canonical constant to prevent it being transformed back into a BUILD_VECTOR, leading to an infinite loop.
1 parent 62abc8c commit 3f81841

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21408,6 +21408,13 @@ bool AArch64TargetLowering::SimplifyDemandedBitsForTargetNode(
2140821408
Op, OriginalDemandedBits, OriginalDemandedElts, Known, TLO, Depth);
2140921409
}
2141021410

21411+
bool AArch64TargetLowering::isTargetCanonicalConstantNode(SDValue Op) const {
21412+
return Op.getOpcode() == AArch64ISD::DUP ||
21413+
(Op.getOpcode() == ISD::EXTRACT_SUBVECTOR &&
21414+
Op.getOperand(0).getOpcode() == AArch64ISD::DUP) ||
21415+
TargetLowering::isTargetCanonicalConstantNode(Op);
21416+
}
21417+
2141121418
bool AArch64TargetLowering::isConstantUnsignedBitfieldExtractLegal(
2141221419
unsigned Opc, LLT Ty1, LLT Ty2) const {
2141321420
return Ty1 == Ty2 && (Ty1 == LLT::scalar(32) || Ty1 == LLT::scalar(64));

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,10 +1129,7 @@ class AArch64TargetLowering : public TargetLowering {
11291129
TargetLoweringOpt &TLO,
11301130
unsigned Depth) const override;
11311131

1132-
bool isTargetCanonicalConstantNode(SDValue Op) const override {
1133-
return Op.getOpcode() == AArch64ISD::DUP ||
1134-
TargetLowering::isTargetCanonicalConstantNode(Op);
1135-
}
1132+
bool isTargetCanonicalConstantNode(SDValue Op) const override;
11361133

11371134
// Normally SVE is only used for byte size vectors that do not fit within a
11381135
// NEON vector. This changes when OverrideNEON is true, allowing SVE to be

llvm/test/CodeGen/AArch64/arm64-dup.ll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,3 +460,47 @@ define void @disguised_dup(<4 x float> %x, <4 x float>* %p1, <4 x float>* %p2) {
460460
store <4 x float> %dup, <4 x float>* %p2, align 8
461461
ret void
462462
}
463+
464+
define <2 x i32> @dup_const2(<2 x i32> %A) nounwind {
465+
; CHECK-LABEL: dup_const2:
466+
; CHECK: // %bb.0:
467+
; CHECK-NEXT: mov w8, #32770
468+
; CHECK-NEXT: movk w8, #128, lsl #16
469+
; CHECK-NEXT: dup.2s v1, w8
470+
; CHECK-NEXT: add.2s v0, v0, v1
471+
; CHECK-NEXT: ret
472+
%tmp2 = add <2 x i32> %A, <i32 8421378, i32 8421378>
473+
ret <2 x i32> %tmp2
474+
}
475+
476+
define <2 x i32> @dup_const4_ext(<4 x i32> %A) nounwind {
477+
; CHECK-LABEL: dup_const4_ext:
478+
; CHECK: // %bb.0:
479+
; CHECK-NEXT: mov w8, #32769
480+
; CHECK-NEXT: movk w8, #128, lsl #16
481+
; CHECK-NEXT: dup.2s v1, w8
482+
; CHECK-NEXT: add.2s v0, v0, v1
483+
; CHECK-NEXT: ret
484+
%tmp1 = add <4 x i32> %A, <i32 8421377, i32 8421377, i32 8421377, i32 8421377>
485+
%tmp2 = shufflevector <4 x i32> %tmp1, <4 x i32> undef, <2 x i32> <i32 0, i32 1>
486+
ret <2 x i32> %tmp2
487+
}
488+
489+
define <4 x i32> @dup_const24(<2 x i32> %A, <2 x i32> %B, <4 x i32> %C) nounwind {
490+
; CHECK-LABEL: dup_const24:
491+
; CHECK: // %bb.0:
492+
; CHECK-NEXT: mov w8, #32768
493+
; CHECK-NEXT: // kill: def $d1 killed $d1 def $q1
494+
; CHECK-NEXT: movk w8, #128, lsl #16
495+
; CHECK-NEXT: dup.4s v3, w8
496+
; CHECK-NEXT: add.2s v0, v0, v3
497+
; CHECK-NEXT: mov.d v0[1], v1[0]
498+
; CHECK-NEXT: add.4s v1, v2, v3
499+
; CHECK-NEXT: eor.16b v0, v1, v0
500+
; CHECK-NEXT: ret
501+
%tmp1 = add <2 x i32> %A, <i32 8421376, i32 8421376>
502+
%tmp4 = shufflevector <2 x i32> %tmp1, <2 x i32> %B, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
503+
%tmp3 = add <4 x i32> %C, <i32 8421376, i32 8421376, i32 8421376, i32 8421376>
504+
%tmp5 = xor <4 x i32> %tmp3, %tmp4
505+
ret <4 x i32> %tmp5
506+
}

0 commit comments

Comments
 (0)