From c1909d73372e669a44a2aefe82de873c2161cc44 Mon Sep 17 00:00:00 2001 From: "chenglin.bi" Date: Sat, 15 Oct 2022 01:16:19 +0800 Subject: [PATCH] [DAGCombiner] Fix crash for the merge stores with different value type The crash case comes from #58350. It have two stores, one store is type f32 and the other is v1f32. When we try to merge these two stores on v1f32, the memVT is vector type so the old code will use ISD::EXTRACT_SUBVECTOR for type f32 also then compiler crash. So this patch insert a build_vector for f32 store to generate v1f32 also when memVT is v1f32. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D135954 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 ++ llvm/test/CodeGen/AArch64/pr58350.ll | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 llvm/test/CodeGen/AArch64/pr58350.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 467459dbbaee..c3868b9557ff 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -18321,6 +18321,9 @@ bool DAGCombiner::mergeStoresOfConstantsOrVecElts( // We may need to add a bitcast here to get types to line up. if (MemVTScalarTy != Val.getValueType().getScalarType()) { Val = DAG.getBitcast(MemVT, Val); + } else if (MemVT.isVector() && + Val.getOpcode() == ISD::EXTRACT_VECTOR_ELT) { + Val = DAG.getNode(ISD::BUILD_VECTOR, DL, MemVT, Val); } else { unsigned OpC = MemVT.isVector() ? ISD::EXTRACT_SUBVECTOR : ISD::EXTRACT_VECTOR_ELT; diff --git a/llvm/test/CodeGen/AArch64/pr58350.ll b/llvm/test/CodeGen/AArch64/pr58350.ll new file mode 100644 index 000000000000..eaabb3d0cd40 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/pr58350.ll @@ -0,0 +1,31 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s + +; This used to hit an assertion caused by dagcombine merge store. +; When the store memVT is v1f32 and the other store to be merged +; is f32, we need to build vector for the f32 store. + +define void @f(<1 x float> %a, i64 %b) { +; CHECK-LABEL: f: +; CHECK: // %bb.0: +; CHECK-NEXT: sub sp, sp, #16 +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: adrp x8, .LCPI0_0 +; CHECK-NEXT: and x9, x0, #0x1 +; CHECK-NEXT: mov x10, sp +; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0 +; CHECK-NEXT: ldr d1, [x8, :lo12:.LCPI0_0] +; CHECK-NEXT: bfi x10, x9, #2, #1 +; CHECK-NEXT: str d1, [sp] +; CHECK-NEXT: ldr s1, [x10] +; CHECK-NEXT: mov v1.s[1], v0.s[0] +; CHECK-NEXT: str d1, [sp, #8] +; CHECK-NEXT: add sp, sp, #16 +; CHECK-NEXT: ret + %P = alloca i64 + %E = extractelement <2 x float> , i64 %b + %G = getelementptr <1 x float>, ptr %P, i64 1 + store float %E, ptr %P + store <1 x float> %a, ptr %G + ret void +} -- 2.34.1