[Hexagon] Widen vector types with non-power-of-2 element counts
authorKrzysztof Parzyszek <kparzysz@quicinc.com>
Mon, 30 May 2022 19:14:59 +0000 (12:14 -0700)
committerKrzysztof Parzyszek <kparzysz@quicinc.com>
Mon, 30 May 2022 19:57:48 +0000 (12:57 -0700)
Such vector types cannot be split at the moment, because splitting expects
an even number of elements in the source type. If a target marks such a type
as "split", TargetLoweringBase::computeRegisterProperties will override it
with widening to the next power of 2. This could lead to issues during
instruction selection when conflicting information about how to handle this
type is present.

llvm/lib/Target/Hexagon/HexagonISelLowering.cpp
llvm/test/CodeGen/Hexagon/isel-v3i16.ll [new file with mode: 0644]

index 11dd8e2..9a3f65b 100644 (file)
@@ -2163,6 +2163,11 @@ HexagonTargetLowering::getPreferredVectorAction(MVT VT) const {
   // Always widen (remaining) vectors of i1.
   if (ElemTy == MVT::i1)
     return TargetLoweringBase::TypeWidenVector;
+  // Widen non-power-of-2 vectors. Such types cannot be split right now,
+  // and computeRegisterProperties will override "split" with "widen",
+  // which can cause other issues.
+  if (!isPowerOf2_32(VecLen))
+    return TargetLoweringBase::TypeWidenVector;
 
   return TargetLoweringBase::TypeSplitVector;
 }
diff --git a/llvm/test/CodeGen/Hexagon/isel-v3i16.ll b/llvm/test/CodeGen/Hexagon/isel-v3i16.ll
new file mode 100644 (file)
index 0000000..ddca7f4
--- /dev/null
@@ -0,0 +1,40 @@
+; RUN: llc -march=hexagon < %s | FileCheck %s
+
+; Check for a successful compilation.
+; CHECK: callr
+
+target datalayout = "e-m:e-p:32:32:32-a:0-n16:32-i64:64:64-i32:32:32-i16:16:16-i1:8:8-f32:32:32-f64:64:64-v32:32:32-v64:64:64-v512:512:512-v1024:1024:1024-v2048:2048:2048"
+target triple = "hexagon"
+
+@g0 = external dllexport global i8* (i32, i32, i64, i32, i32)*, align 4
+
+define hidden void @f0(i32 %a0, <3 x i16>* %a1) #0 {
+b0:
+  %v0 = load i8* (i32, i32, i64, i32, i32)*, i8* (i32, i32, i64, i32, i32)** @g0, align 4
+  %v1 = call i8* %v0(i32 1, i32 %a0, i64 314646, i32 0, i32 16)
+  br label %b1
+
+b1:                                               ; preds = %b2, %b0
+  br label %b2
+
+b2:                                               ; preds = %b5, %b1
+  %v2 = icmp slt i32 0, 229
+  br i1 %v2, label %b3, label %b1
+
+b3:                                               ; preds = %b2
+  br i1 undef, label %b4, label %b5
+
+b4:                                               ; preds = %b3
+  %v3 = load <3 x i16>, <3 x i16>* %a1, align 2
+  br label %b5
+
+b5:                                               ; preds = %b4, %b3
+  %v4 = phi <3 x i16> [ %v3, %b4 ], [ zeroinitializer, %b3 ]
+  %v5 = bitcast i8* %v1 to i16*
+  %v6 = getelementptr inbounds i16, i16* %v5, i32 undef
+  %v7 = bitcast i16* %v6 to <3 x i16>*
+  store <3 x i16> %v4, <3 x i16>* %v7, align 2
+  br label %b2
+}
+
+attributes #0 = { "target-cpu"="hexagonv68" }