[DAGCombiner] Fix crash for the merge stores with different value type
authorchenglin.bi <chenglin.bi@linaro.org>
Fri, 14 Oct 2022 17:16:19 +0000 (01:16 +0800)
committerchenglin.bi <chenglin.bi@linaro.org>
Fri, 14 Oct 2022 17:16:35 +0000 (01:16 +0800)
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
llvm/test/CodeGen/AArch64/pr58350.ll [new file with mode: 0644]

index 467459d..c3868b9 100644 (file)
@@ -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 (file)
index 0000000..eaabb3d
--- /dev/null
@@ -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> <float 0.5, float 1.0>, 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
+}