diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -20267,7 +20267,9 @@ // Replace a SCALAR_TO_VECTOR(EXTRACT_VECTOR_ELT(V,C0)) pattern // with a VECTOR_SHUFFLE and possible truncate. - if (InVal.getOpcode() == ISD::EXTRACT_VECTOR_ELT) { + if (InVal.getOpcode() == ISD::EXTRACT_VECTOR_ELT && + VT.isFixedLengthVector() && + InVal->getOperand(0).getValueType().isFixedLengthVector()) { SDValue InVec = InVal->getOperand(0); SDValue EltNo = InVal->getOperand(1); auto InVecT = InVec.getValueType(); diff --git a/llvm/test/CodeGen/AArch64/sve-fp.ll b/llvm/test/CodeGen/AArch64/sve-fp.ll --- a/llvm/test/CodeGen/AArch64/sve-fp.ll +++ b/llvm/test/CodeGen/AArch64/sve-fp.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s 2>%t | FileCheck %s ; RUN: FileCheck --check-prefix=WARN --allow-empty %s <%t @@ -5,124 +6,158 @@ define @fadd_h( %a, %b) { ; CHECK-LABEL: fadd_h: -; CHECK: fadd z0.h, z0.h, z1.h -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fadd z0.h, z0.h, z1.h +; CHECK-NEXT: ret %res = fadd %a, %b ret %res } define @fadd_s( %a, %b) { ; CHECK-LABEL: fadd_s: -; CHECK: fadd z0.s, z0.s, z1.s -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fadd z0.s, z0.s, z1.s +; CHECK-NEXT: ret %res = fadd %a, %b ret %res } define @fadd_d( %a, %b) { ; CHECK-LABEL: fadd_d: -; CHECK: fadd z0.d, z0.d, z1.d -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fadd z0.d, z0.d, z1.d +; CHECK-NEXT: ret %res = fadd %a, %b ret %res } define @fsub_h( %a, %b) { ; CHECK-LABEL: fsub_h: -; CHECK: fsub z0.h, z0.h, z1.h -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fsub z0.h, z0.h, z1.h +; CHECK-NEXT: ret %res = fsub %a, %b ret %res } define @fsub_s( %a, %b) { ; CHECK-LABEL: fsub_s: -; CHECK: fsub z0.s, z0.s, z1.s -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fsub z0.s, z0.s, z1.s +; CHECK-NEXT: ret %res = fsub %a, %b ret %res } define @fsub_d( %a, %b) { ; CHECK-LABEL: fsub_d: -; CHECK: fsub z0.d, z0.d, z1.d -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fsub z0.d, z0.d, z1.d +; CHECK-NEXT: ret %res = fsub %a, %b ret %res } define @fmul_h( %a, %b) { ; CHECK-LABEL: fmul_h: -; CHECK: fmul z0.h, z0.h, z1.h -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fmul z0.h, z0.h, z1.h +; CHECK-NEXT: ret %res = fmul %a, %b ret %res } define @fmul_s( %a, %b) { ; CHECK-LABEL: fmul_s: -; CHECK: fmul z0.s, z0.s, z1.s -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fmul z0.s, z0.s, z1.s +; CHECK-NEXT: ret %res = fmul %a, %b ret %res } define @fmul_d( %a, %b) { ; CHECK-LABEL: fmul_d: -; CHECK: fmul z0.d, z0.d, z1.d -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: fmul z0.d, z0.d, z1.d +; CHECK-NEXT: ret %res = fmul %a, %b ret %res } define @frecps_h( %a, %b) { ; CHECK-LABEL: frecps_h: -; CHECK: frecps z0.h, z0.h, z1.h -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: frecps z0.h, z0.h, z1.h +; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.frecps.x.nxv8f16( %a, %b) ret %res } define @frecps_s( %a, %b) { ; CHECK-LABEL: frecps_s: -; CHECK: frecps z0.s, z0.s, z1.s -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: frecps z0.s, z0.s, z1.s +; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.frecps.x.nxv4f32( %a, %b) ret %res } define @frecps_d( %a, %b) { ; CHECK-LABEL: frecps_d: -; CHECK: frecps z0.d, z0.d, z1.d -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: frecps z0.d, z0.d, z1.d +; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.frecps.x.nxv2f64( %a, %b) ret %res } define @frsqrts_h( %a, %b) { ; CHECK-LABEL: frsqrts_h: -; CHECK: frsqrts z0.h, z0.h, z1.h -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: frsqrts z0.h, z0.h, z1.h +; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.frsqrts.x.nxv8f16( %a, %b) ret %res } define @frsqrts_s( %a, %b) { ; CHECK-LABEL: frsqrts_s: -; CHECK: frsqrts z0.s, z0.s, z1.s -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: frsqrts z0.s, z0.s, z1.s +; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.frsqrts.x.nxv4f32( %a, %b) ret %res } define @frsqrts_d( %a, %b) { ; CHECK-LABEL: frsqrts_d: -; CHECK: frsqrts z0.d, z0.d, z1.d -; CHECK-NEXT: ret +; CHECK: // %bb.0: +; CHECK-NEXT: frsqrts z0.d, z0.d, z1.d +; CHECK-NEXT: ret %res = call @llvm.aarch64.sve.frsqrts.x.nxv2f64( %a, %b) ret %res } +%complex = type { { double, double } } + +define void @scalar_to_vector(%complex* %outval, %pred, %in1, %in2) { +; CHECK-LABEL: scalar_to_vector: +; CHECK: // %bb.0: +; CHECK-NEXT: faddv d0, p0, z0.d +; CHECK-NEXT: faddv d1, p0, z1.d +; CHECK-NEXT: mov v0.d[1], v1.d[0] +; CHECK-NEXT: str q0, [x0] +; CHECK-NEXT: ret + %realp = getelementptr inbounds %complex, %complex* %outval, i64 0, i32 0, i32 0 + %imagp = getelementptr inbounds %complex, %complex* %outval, i64 0, i32 0, i32 1 + %1 = call double @llvm.aarch64.sve.faddv.nxv2f64( %pred, %in1) + %2 = call double @llvm.aarch64.sve.faddv.nxv2f64( %pred, %in2) + store double %1, double* %realp, align 8 + store double %2, double* %imagp, align 8 + ret void +} + declare @llvm.aarch64.sve.frecps.x.nxv8f16(, ) declare @llvm.aarch64.sve.frecps.x.nxv4f32( , ) declare @llvm.aarch64.sve.frecps.x.nxv2f64(, ) @@ -130,3 +165,6 @@ declare @llvm.aarch64.sve.frsqrts.x.nxv8f16(, ) declare @llvm.aarch64.sve.frsqrts.x.nxv4f32(, ) declare @llvm.aarch64.sve.frsqrts.x.nxv2f64(, ) + +; Function Attrs: nounwind readnone +declare double @llvm.aarch64.sve.faddv.nxv2f64(, ) #2