[Hexagon] Handle instruction selection for select(I1,Q,Q)
authorIkhlas Ajbar <iajbar@quicinc.com>
Thu, 16 Apr 2020 20:56:56 +0000 (15:56 -0500)
committerKrzysztof Parzyszek <kparzysz@quicinc.com>
Wed, 5 Jan 2022 22:50:12 +0000 (14:50 -0800)
Lower select(I1,Q,Q) by converting vector predicate Q to vector register V,
doing select(I1,V,V), and then converting the resulting V back to Q. Also,
try to avoid creating such situations in the first place.

llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp
llvm/lib/Target/Hexagon/HexagonPatternsHVX.td
llvm/test/CodeGen/Hexagon/select-vector-pred.ll [new file with mode: 0644]

index 2679e39..0225cc5 100644 (file)
@@ -1176,6 +1176,9 @@ void HexagonDAGToDAGISel::ppHoistZextI1(std::vector<SDNode*> &&Nodes) {
       EVT UVT = U->getValueType(0);
       if (!UVT.isSimple() || !UVT.isInteger() || UVT.getSimpleVT() == MVT::i1)
         continue;
+      // Do not generate select for all i1 vector type.
+      if (UVT.isVector() && UVT.getVectorElementType() == MVT::i1)
+        continue;
       if (isMemOPCandidate(N, U))
         continue;
 
index 2e739d6..0a3dff0 100644 (file)
@@ -736,6 +736,12 @@ let Predicates = [UseHVX] in {
   def: HvxSel_pat<PS_wselect, HWI32>;
 }
 
+def V2Q: OutPatFrag<(ops node:$Vs), (V6_vandvrt $Vs, (A2_tfrsi -1))>;
+
+let Predicates = [UseHVX] in
+  def: Pat<(select I1:$Pu, VecI1:$Qs, VecI1:$Qt),
+           (V2Q (PS_vselect $Pu, (Q2V $Qs), (Q2V $Qt)))>;
+
 let Predicates = [UseHVX] in {
   def: Pat<(VecQ8   (qtrue)), (PS_qtrue)>;
   def: Pat<(VecQ16  (qtrue)), (PS_qtrue)>;
diff --git a/llvm/test/CodeGen/Hexagon/select-vector-pred.ll b/llvm/test/CodeGen/Hexagon/select-vector-pred.ll
new file mode 100644 (file)
index 0000000..58a052c
--- /dev/null
@@ -0,0 +1,30 @@
+; RUN: llc -march=hexagon -mcpu=hexagonv68 -mattr=+hvxv68,+hvx-length128b < %s | FileCheck %s
+
+; Do not generate selectI1,Q,Q.
+; CHECK: q[[Q:[0-9]+]] = vsetq(r{{[0-9]+}})
+; CHECK: q{{[0-9]+}} = and(q{{[0-9]+}},q[[Q]])
+; CHECK-NOT: v{{[0-9]+}} = vand(q{{[0-9]+}},r{{[0-9]+}})
+
+target triple = "hexagon"
+
+declare void @llvm.hexagon.V6.vS32b.qpred.ai.128B(<128 x i1>, i8*, <32 x i32>) #0
+declare <128 x i1> @llvm.hexagon.V6.pred.scalar2.128B(i32) #1
+declare <128 x i1> @llvm.hexagon.V6.pred.and.128B(<128 x i1>, <128 x i1>) #1
+
+define void @libjit_convertFromD32_sm_hf_wrap_3_specialized(i16* %0) local_unnamed_addr #2 {
+entry:
+  %arrayidx55.i.i = getelementptr inbounds i16, i16* %0, i32 undef
+  %1 = ptrtoint i16* %arrayidx55.i.i to i32
+  %and.i5.i.i = and i32 %1, 127
+  %2 = icmp eq i32 %and.i5.i.i, 127
+  %.sroa.speculated.i13.i.i = zext i1 %2 to i32
+  %3 = tail call <128 x i1> @llvm.hexagon.V6.pred.scalar2.128B(i32 %.sroa.speculated.i13.i.i) #3
+  %4 = tail call <128 x i1> @llvm.hexagon.V6.pred.and.128B(<128 x i1> undef, <128 x i1> %3) #3
+  tail call void @llvm.hexagon.V6.vS32b.qpred.ai.128B(<128 x i1> %4, i8* nonnull undef, <32 x i32> undef) #3
+  unreachable
+                  }
+
+attributes #0 = { nounwind writeonly }
+attributes #1 = { nounwind readnone }
+attributes #2 = { "use-soft-float"="false" }
+attributes #3 = { nounwind }