[PATCH] D124997: [InstCombine] Fix scalable-vector bitwise select matching

Fraser Cormack via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 5 03:23:29 PDT 2022


frasercrmck created this revision.
frasercrmck added reviewers: spatel, lebedev.ri, dmgreen, craig.topper.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
frasercrmck requested review of this revision.
Herald added subscribers: llvm-commits, alextsao1999.
Herald added a project: LLVM.

D113035 <https://reviews.llvm.org/D113035> enhanced the matching of bitwise selects from vector types. This
change unfortunately introduced crashes as it tries to cast scalable
vector types to integers.

This optimization is still valid for scalable vector types as long as
there are no bitcasts to be made. Thus the optimization now checks this
case explicitly, rather than relying on the code producing the same
type (and thus no-op bitcasts) if no bitcasts are needed.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124997

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/logical-select.ll


Index: llvm/test/Transforms/InstCombine/logical-select.ll
===================================================================
--- llvm/test/Transforms/InstCombine/logical-select.ll
+++ llvm/test/Transforms/InstCombine/logical-select.ll
@@ -471,6 +471,18 @@
   ret <4 x i1> %or
 }
 
+define <vscale x 1 x i1> @vec_of_bools_scalable(<vscale x 1 x i1> %a, <vscale x 1 x i1> %c, <vscale x 1 x i1> %d) {
+; CHECK-LABEL: @vec_of_bools_scalable(
+; CHECK-NEXT:    [[TMP1:%.*]] = select <vscale x 1 x i1> [[A:%.*]], <vscale x 1 x i1> [[C:%.*]], <vscale x 1 x i1> [[D:%.*]]
+; CHECK-NEXT:    ret <vscale x 1 x i1> [[TMP1]]
+;
+  %b = xor <vscale x 1 x i1> %a, shufflevector (<vscale x 1 x i1> insertelement (<vscale x 1 x i1> poison, i1 true, i32 0), <vscale x 1 x i1> poison, <vscale x 1 x i32> zeroinitializer)
+  %t11 = and <vscale x 1 x i1> %a, %c
+  %t12 = and <vscale x 1 x i1> %b, %d
+  %r = or <vscale x 1 x i1> %t11, %t12
+  ret <vscale x 1 x i1> %r
+}
+
 define i4 @vec_of_casted_bools(i4 %a, i4 %b, <4 x i1> %c) {
 ; CHECK-LABEL: @vec_of_casted_bools(
 ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i4 [[B:%.*]] to <4 x i1>
@@ -488,6 +500,31 @@
   ret i4 %or
 }
 
+; Negative test - we can't create the correct scalable vector casts
+
+define <vscale x 1 x i64> @vec_of_casted_bools_scalable(<vscale x 1 x i64> %a, <vscale x 1 x i64> %b, <vscale x 8 x i1> %cond) {
+; CHECK-LABEL: @vec_of_casted_bools_scalable(
+; CHECK-NEXT:    [[SCOND:%.*]] = sext <vscale x 8 x i1> [[COND:%.*]] to <vscale x 8 x i8>
+; CHECK-NEXT:    [[NOTCOND:%.*]] = xor <vscale x 8 x i1> [[COND]], shufflevector (<vscale x 8 x i1> insertelement (<vscale x 8 x i1> poison, i1 true, i32 0), <vscale x 8 x i1> poison, <vscale x 8 x i32> zeroinitializer)
+; CHECK-NEXT:    [[SNOTCOND:%.*]] = sext <vscale x 8 x i1> [[NOTCOND]] to <vscale x 8 x i8>
+; CHECK-NEXT:    [[BC1:%.*]] = bitcast <vscale x 8 x i8> [[SCOND]] to <vscale x 1 x i64>
+; CHECK-NEXT:    [[BC2:%.*]] = bitcast <vscale x 8 x i8> [[SNOTCOND]] to <vscale x 1 x i64>
+; CHECK-NEXT:    [[AND1:%.*]] = and <vscale x 1 x i64> [[BC1]], [[A:%.*]]
+; CHECK-NEXT:    [[AND2:%.*]] = and <vscale x 1 x i64> [[BC2]], [[B:%.*]]
+; CHECK-NEXT:    [[OR:%.*]] = or <vscale x 1 x i64> [[AND1]], [[AND2]]
+; CHECK-NEXT:    ret <vscale x 1 x i64> [[OR]]
+;
+  %scond = sext <vscale x 8 x i1> %cond to <vscale x 8 x i8>
+  %notcond = xor <vscale x 8 x i1> %cond, shufflevector (<vscale x 8 x i1> insertelement (<vscale x 8 x i1> poison, i1 true, i32 0), <vscale x 8 x i1> poison, <vscale x 8 x i32> zeroinitializer)
+  %snotcond = sext <vscale x 8 x i1> %notcond to <vscale x 8 x i8>
+  %bc1 = bitcast <vscale x 8 x i8> %scond to <vscale x 1 x i64>
+  %bc2 = bitcast <vscale x 8 x i8> %snotcond to <vscale x 1 x i64>
+  %and1 = and <vscale x 1 x i64> %a, %bc1
+  %and2 = and <vscale x 1 x i64> %bc2, %b
+  %or = or <vscale x 1 x i64> %and1, %and2
+  ret <vscale x 1 x i64> %or
+}
+
 ; Inverted 'and' constants mean this is a select which is canonicalized to a shuffle.
 
 define <4 x i32> @vec_sel_consts(<4 x i32> %a, <4 x i32> %b) {
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2343,7 +2343,12 @@
     // The bitcasts will either all exist or all not exist. The builder will
     // not create unnecessary casts if the types already match.
     Type *SelTy = A->getType();
-    if (auto *VecTy = dyn_cast<VectorType>(Cond->getType())) {
+    auto *VecTy = dyn_cast<VectorType>(Cond->getType());
+    // Check whether we have to cast.
+    if (VecTy && VecTy != C->getType()) {
+      // If we do have to cast, we must avoid scalable vectors here.
+      if (VecTy->getElementCount().isScalable())
+        return nullptr;
       unsigned Elts = VecTy->getElementCount().getKnownMinValue();
       Type *EltTy = Builder.getIntNTy(SelTy->getPrimitiveSizeInBits() / Elts);
       SelTy = VectorType::get(EltTy, VecTy->getElementCount());


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124997.427253.patch
Type: text/x-patch
Size: 4058 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220505/9aa9944a/attachment.bin>


More information about the llvm-commits mailing list