[llvm] 1206313 - [CodeGen][AArch64] Fix isel crash for truncating FP stores

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 8 05:21:51 PDT 2021


Author: David Sherwood
Date: 2021-04-08T13:21:29+01:00
New Revision: 1206313f82f819381055dc730294ef50b3af63c9

URL: https://github.com/llvm/llvm-project/commit/1206313f82f819381055dc730294ef50b3af63c9
DIFF: https://github.com/llvm/llvm-project/commit/1206313f82f819381055dc730294ef50b3af63c9.diff

LOG: [CodeGen][AArch64] Fix isel crash for truncating FP stores

When attempting to truncate a FP vector and store the result out
to memory we crashed because we had no pattern for truncating FP
stores. In fact, we don't support these types of stores and the
correct fix is to stop marking these truncating stores as legal.

Tests have been added here:

  CodeGen/AArch64/sve-fptrunc-store.ll

Differential Revision: https://reviews.llvm.org/D100025

Added: 
    llvm/test/CodeGen/AArch64/sve-fptrunc-store.ll

Modified: 
    llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index b40fb7e1a12b..718fc8b7c1d0 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -1180,6 +1180,13 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
 
     for (auto VT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16, MVT::nxv2f32,
                     MVT::nxv4f32, MVT::nxv2f64}) {
+      for (auto InnerVT : {MVT::nxv2f16, MVT::nxv4f16, MVT::nxv8f16,
+                           MVT::nxv2f32, MVT::nxv4f32, MVT::nxv2f64}) {
+        // Avoid marking truncating FP stores as legal to prevent the
+        // DAGCombiner from creating unsupported truncating stores.
+        setTruncStoreAction(VT, InnerVT, Expand);
+      }
+
       setOperationAction(ISD::CONCAT_VECTORS, VT, Custom);
       setOperationAction(ISD::INSERT_SUBVECTOR, VT, Custom);
       setOperationAction(ISD::MGATHER, VT, Custom);

diff  --git a/llvm/test/CodeGen/AArch64/sve-fptrunc-store.ll b/llvm/test/CodeGen/AArch64/sve-fptrunc-store.ll
new file mode 100644
index 000000000000..41bca595a25e
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sve-fptrunc-store.ll
@@ -0,0 +1,62 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve < %s | FileCheck %s
+
+define void @fptrunc2_f64_f32(<vscale x 2 x float> *%dst, <vscale x 2 x double> *%src) {
+; CHECK-LABEL: fptrunc2_f64_f32:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ptrue p0.d
+; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x1]
+; CHECK-NEXT:    fcvt z0.s, p0/m, z0.d
+; CHECK-NEXT:    st1w { z0.d }, p0, [x0]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <vscale x 2 x double>, <vscale x 2 x double>* %src, align 8
+  %1 = fptrunc <vscale x 2 x double> %0 to <vscale x 2 x float>
+  store <vscale x 2 x float> %1, <vscale x 2 x float>* %dst, align 4
+  ret void
+}
+
+define void @fptrunc2_f64_f16(<vscale x 2 x half> *%dst, <vscale x 2 x double> *%src) {
+; CHECK-LABEL: fptrunc2_f64_f16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ptrue p0.d
+; CHECK-NEXT:    ld1d { z0.d }, p0/z, [x1]
+; CHECK-NEXT:    fcvt z0.h, p0/m, z0.d
+; CHECK-NEXT:    st1h { z0.d }, p0, [x0]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <vscale x 2 x double>, <vscale x 2 x double>* %src, align 8
+  %1 = fptrunc <vscale x 2 x double> %0 to <vscale x 2 x half>
+  store <vscale x 2 x half> %1, <vscale x 2 x half>* %dst, align 2
+  ret void
+}
+
+define void @fptrunc4_f32_f16(<vscale x 4 x half> *%dst, <vscale x 4 x float> *%src) {
+; CHECK-LABEL: fptrunc4_f32_f16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ptrue p0.s
+; CHECK-NEXT:    ld1w { z0.s }, p0/z, [x1]
+; CHECK-NEXT:    fcvt z0.h, p0/m, z0.s
+; CHECK-NEXT:    st1h { z0.s }, p0, [x0]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <vscale x 4 x float>, <vscale x 4 x float>* %src, align 8
+  %1 = fptrunc <vscale x 4 x float> %0 to <vscale x 4 x half>
+  store <vscale x 4 x half> %1, <vscale x 4 x half>* %dst, align 2
+  ret void
+}
+
+define void @fptrunc2_f32_f16(<vscale x 2 x half> *%dst, <vscale x 2 x float> *%src) {
+; CHECK-LABEL: fptrunc2_f32_f16:
+; CHECK:       // %bb.0: // %entry
+; CHECK-NEXT:    ptrue p0.d
+; CHECK-NEXT:    ld1w { z0.d }, p0/z, [x1]
+; CHECK-NEXT:    fcvt z0.h, p0/m, z0.s
+; CHECK-NEXT:    st1h { z0.d }, p0, [x0]
+; CHECK-NEXT:    ret
+entry:
+  %0 = load <vscale x 2 x float>, <vscale x 2 x float>* %src, align 8
+  %1 = fptrunc <vscale x 2 x float> %0 to <vscale x 2 x half>
+  store <vscale x 2 x half> %1, <vscale x 2 x half>* %dst, align 2
+  ret void
+}


        


More information about the llvm-commits mailing list