mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-05 10:17:36 +00:00
[AArch64] Fix SelectionDAG infinite loop for v1i64 SCALAR_TO_VECTOR
A consequence of r347274 is that SCALAR_TO_VECTOR can be converted into BUILD_VECTOR by SimplifyDemandedBits, but LowerBUILD_VECTOR can turn BUILD_VECTOR into SCALAR_TO_VECTOR so we get an infinite loop. Fix this by making LowerBUILD_VECTOR not do this transformation for those vectors that would get transformed back, i.e. BUILD_VECTOR of a single-element constant vector. Doing that means we get a DUP, which we then need to recognise in ISel as a copy. llvm-svn: 347456
This commit is contained in:
parent
f196353c66
commit
0cab72eb19
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user