diff options
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.td | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/arm64-build-vector.ll | 22 |
3 files changed, 32 insertions, 1 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp index 92223c8e897..0df4c05eb1c 100644 --- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -7260,7 +7260,10 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op, return DAG.getUNDEF(VT); } - if (isOnlyLowElement) { + // Convert BUILD_VECTOR where all elements but the lowest are undef into + // SCALAR_TO_VECTOR, except for when we have a single-element constant vector + // as SimplifyDemandedBits will just turn that back into BUILD_VECTOR. + if (isOnlyLowElement && !(NumElts == 1 && isa<ConstantSDNode>(Value))) { LLVM_DEBUG(dbgs() << "LowerBUILD_VECTOR: only low element used, creating 1 " "SCALAR_TO_VECTOR node\n"); return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value); diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index 3c949f5d6f6..84aedaafffe 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -4349,6 +4349,12 @@ def DUPv8i16lane : SIMDDup16FromElement<1, ".8h", v8i16, V128>; def DUPv8i8lane : SIMDDup8FromElement <0, ".8b", v8i8, V64>; def DUPv16i8lane : SIMDDup8FromElement <1, ".16b", v16i8, V128>; +// DUP from a 64-bit register to a 64-bit register is just a copy +def : Pat<(v1i64 (AArch64dup (i64 GPR64:$Rn))), + (COPY_TO_REGCLASS GPR64:$Rn, FPR64)>; +def : Pat<(v1f64 (AArch64dup (f64 FPR64:$Rn))), + (COPY_TO_REGCLASS FPR64:$Rn, FPR64)>; + def : Pat<(v2f32 (AArch64dup (f32 FPR32:$Rn))), (v2f32 (DUPv2i32lane (INSERT_SUBREG (v4i32 (IMPLICIT_DEF)), FPR32:$Rn, ssub), diff --git a/llvm/test/CodeGen/AArch64/arm64-build-vector.ll b/llvm/test/CodeGen/AArch64/arm64-build-vector.ll index d7fe9c6d68b..d268f761c9a 100644 --- a/llvm/test/CodeGen/AArch64/arm64-build-vector.ll +++ b/llvm/test/CodeGen/AArch64/arm64-build-vector.ll @@ -53,3 +53,25 @@ define void @widen_f16_build_vector(half* %addr) { store <2 x half> <half 0xH33EE, half 0xH33EE>, <2 x half>* %1, align 2 ret void } + +; Check that a single element vector is constructed with a mov +define <1 x i64> @single_element_vector_i64(<1 x i64> %arg) { +; CHECK-LABEL: single_element_vector_i64 +; CHECK: orr w[[GREG:[0-9]+]], wzr, #0x1 +; CHECK: fmov d[[DREG:[0-9]+]], x[[GREG]] +; CHECK: add d0, d0, d[[DREG]] +; CHECK: ret +entry: + %add = add <1 x i64> %arg, <i64 1> + ret <1 x i64> %add +} + +define <1 x double> @single_element_vector_double(<1 x double> %arg) { +; CHECK-LABEL: single_element_vector_double +; CHECK: fmov d[[DREG:[0-9]+]], #1.00000000 +; CHECK: fadd d0, d0, d[[DREG]] +; CHECK: ret +entry: + %add = fadd <1 x double> %arg, <double 1.0> + ret <1 x double> %add +} |