[PATCH] D76312: [DAGCombiner] Do not fold truncate(build_vector(..)) if it creates an illegal type

Pirama Arumuga Nainar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 17 12:23:55 PDT 2020


pirama created this revision.
pirama added reviewers: RKSimon, srhines.
Herald added subscribers: danielkiss, hiraditya, kristof.beyls.
Herald added a project: LLVM.

It can be the case that a vector type is legal but the corresponding
scalar type is not legal for an architecture (i8 vs. v16i8 on AArch64).
Check if the scalar type created when folding

  truncate(build_vector(x,y)) -> build_vector(truncate(x),truncate(y))

is legal if we are running after the type legalizer.

This fixes https://github.com/android/ndk/issues/1207.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D76312

Files:
  llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  llvm/test/CodeGen/AArch64/dag-combine-trunc-build-vec.ll


Index: llvm/test/CodeGen/AArch64/dag-combine-trunc-build-vec.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/AArch64/dag-combine-trunc-build-vec.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64 < %s | FileCheck %s
+
+; This test is reduced fom https://github.com/android/ndk/issues/1207 for an
+; issue with the following DAGCobmine operation:
+;   truncate(build_vector(x,y)) -> build_vector(truncate(x),truncate(y))
+; The combine should avoid creating illegal types if types have already been
+; legalized.
+
+define void @no_combine(i32 %p) local_unnamed_addr #0 {
+; CHECK-LABEL: no_combine:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    dup v0.4s, w0
+; CHECK-NEXT:    movi v1.4h, #4
+; CHECK-NEXT:    xtn v0.4h, v0.4s
+; CHECK-NEXT:    mov v0.d[1], v1.d[0]
+; CHECK-NEXT:    xtn v1.8b, v0.8h
+; CHECK-NEXT:    xtn2 v1.16b, v0.8h
+; CHECK-NEXT:    str q1, [x8]
+; CHECK-NEXT:    ret
+
+; The two shufflevector operations are needed to force the DAGCombine to happen
+; after type legalization and before operation legalization.  Removing either
+; makes the combine to happen before type legalization and the issue no longer
+; repros.
+  %1 = insertelement <16 x i32> undef, i32 %p, i32 0
+  %2 = shufflevector <16 x i32> %1, <16 x i32> undef, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i32 undef>
+  %3 = shufflevector <16 x i32> %2, <16 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 4, i32 4, i32 4, i32 4, i32 undef, i32 undef, i32 undef, i32 undef, i32 4, i32 4, i32 4, i32 4>, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 21, i32 22, i32 23, i32 8, i32 9, i32 10, i32 11, i32 28, i32 29, i32 30, i32 31>
+  %4 = trunc <16 x i32> %3 to <16 x i8>
+  %5 = bitcast i8* undef to <16 x i8>*
+  store <16 x i8> %4, <16 x i8>* %5, align 1
+  ret void
+}
+
+; Test case to ensure that the combine is done before type legalization.
+define void @do_combine(i32 %p) local_unnamed_addr #0 {
+; CHECK-LABEL: do_combine:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    dup v0.16b, w0
+; CHECK-NEXT:    str q0, [x8]
+; CHECK-NEXT:    ret
+  %1 = insertelement <16 x i32> undef, i32 %p, i32 0
+  %2 = shufflevector <16 x i32> %1, <16 x i32> undef, <16 x i32> <i32 0, i32 0, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 0, i32 0, i32 0, i32 0, i32 undef, i32 undef, i32 undef, i32 undef>
+  %3 = trunc <16 x i32> %2 to <16 x i8>
+  %4 = bitcast i8* undef to <16 x i8>*
+  store <16 x i8> %3, <16 x i8>* %4, align 1
+  ret void
+}
+
+attributes #0 = { "use-soft-float"="false" }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 11.0.0 (https://github.com/llvm/llvm-project.git c94cfe6ea7f4c2115f817c5836b1481060907e0d)"}
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -11023,7 +11023,9 @@
 
   // Attempt to pre-truncate BUILD_VECTOR sources.
   if (N0.getOpcode() == ISD::BUILD_VECTOR && !LegalOperations &&
-      TLI.isTruncateFree(SrcVT.getScalarType(), VT.getScalarType())) {
+      TLI.isTruncateFree(SrcVT.getScalarType(), VT.getScalarType()) &&
+      // Avoid creating illegal types if running after type legalizer.
+      (!LegalTypes || TLI.isTypeLegal(VT.getScalarType()))) {
     SDLoc DL(N);
     EVT SVT = VT.getScalarType();
     SmallVector<SDValue, 8> TruncOps;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76312.250852.patch
Type: text/x-patch
Size: 3619 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200317/9ebb9e63/attachment.bin>


More information about the llvm-commits mailing list