[PATCH] D97397: [InstCombine] Add a combine for a shuffle of similar bitcasts

Sanne Wouda via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 1 08:27:20 PST 2021


sanwou01 updated this revision to Diff 327126.
sanwou01 added a comment.

Add a few more tests and some further test reduction.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97397/new/

https://reviews.llvm.org/D97397

Files:
  llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
  llvm/test/Transforms/InstCombine/shuffle-cast-dist.ll


Index: llvm/test/Transforms/InstCombine/shuffle-cast-dist.ll
===================================================================
--- llvm/test/Transforms/InstCombine/shuffle-cast-dist.ll
+++ llvm/test/Transforms/InstCombine/shuffle-cast-dist.ll
@@ -4,9 +4,8 @@
 define <2 x float> @vtrn1(<2 x i32> %v)
 ; CHECK-LABEL: @vtrn1(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[VB1:%.*]] = bitcast <2 x i32> [[V:%.*]] to <2 x float>
-; CHECK-NEXT:    [[VB2:%.*]] = bitcast <2 x i32> [[V]] to <2 x float>
-; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[VB1]], <2 x float> [[VB2]], <2 x i32> <i32 0, i32 2>
+; CHECK-NEXT:    [[R_UNCASTED:%.*]] = shufflevector <2 x i32> [[V:%.*]], <2 x i32> undef, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[R:%.*]] = bitcast <2 x i32> [[R_UNCASTED]] to <2 x float>
 ; CHECK-NEXT:    ret <2 x float> [[R]]
 ;
 {
@@ -20,9 +19,8 @@
 define <2 x float> @vtrn2(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-LABEL: @vtrn2(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[XB:%.*]] = bitcast <2 x i32> [[X:%.*]] to <2 x float>
-; CHECK-NEXT:    [[YB:%.*]] = bitcast <2 x i32> [[Y:%.*]] to <2 x float>
-; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[XB]], <2 x float> [[YB]], <2 x i32> <i32 1, i32 3>
+; CHECK-NEXT:    [[R_UNCASTED:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <2 x i32> <i32 1, i32 3>
+; CHECK-NEXT:    [[R:%.*]] = bitcast <2 x i32> [[R_UNCASTED]] to <2 x float>
 ; CHECK-NEXT:    ret <2 x float> [[R]]
 ;
 entry:
@@ -35,9 +33,8 @@
 
 define <4 x float> @bc_shuf_lenchange(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-LABEL: @bc_shuf_lenchange(
-; CHECK-NEXT:    [[XB:%.*]] = bitcast <2 x i32> [[X:%.*]] to <2 x float>
-; CHECK-NEXT:    [[YB:%.*]] = bitcast <2 x i32> [[Y:%.*]] to <2 x float>
-; CHECK-NEXT:    [[R:%.*]] = shufflevector <2 x float> [[XB]], <2 x float> [[YB]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+; CHECK-NEXT:    [[R_UNCASTED:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> [[Y:%.*]], <4 x i32> <i32 3, i32 2, i32 1, i32 0>
+; CHECK-NEXT:    [[R:%.*]] = bitcast <4 x i32> [[R_UNCASTED]] to <4 x float>
 ; CHECK-NEXT:    ret <4 x float> [[R]]
 ;
   %xb = bitcast <2 x i32> %x to <2 x float>
@@ -126,9 +123,9 @@
 define <4 x float> @bc_shuf_y_hasoneuse(<4 x i32> %x, <4 x i32> %y){
 ; CHECK-LABEL: @bc_shuf_y_hasoneuse(
 ; CHECK-NEXT:    [[XB:%.*]] = bitcast <4 x i32> [[X:%.*]] to <4 x float>
-; CHECK-NEXT:    [[YB:%.*]] = bitcast <4 x i32> [[Y:%.*]] to <4 x float>
-; CHECK-NEXT:    [[SHUF:%.*]] = shufflevector <4 x float> [[XB]], <4 x float> [[YB]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
-; CHECK-NEXT:    [[R:%.*]] = fadd <4 x float> [[SHUF]], [[XB]]
+; CHECK-NEXT:    [[SHUF_UNCASTED:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Y:%.*]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; CHECK-NEXT:    [[SHUF:%.*]] = bitcast <4 x i32> [[SHUF_UNCASTED]] to <4 x float>
+; CHECK-NEXT:    [[R:%.*]] = fadd <4 x float> [[XB]], [[SHUF]]
 ; CHECK-NEXT:    ret <4 x float> [[R]]
 ;
   %xb = bitcast <4 x i32> %x to <4 x float>
Index: llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -2289,6 +2289,25 @@
 
   unsigned VWidth = cast<FixedVectorType>(SVI.getType())->getNumElements();
   unsigned LHSWidth = cast<FixedVectorType>(LHS->getType())->getNumElements();
+
+  // shuffle (bitcast X), (bitcast Y), Mask --> bitcast (shuffle X, Y, Mask)
+  //
+  // if X and Y are of the same (vector) type, and the element size is not
+  // changed by the bitcasts, we can distribute the bitcasts through the
+  // shuffle, hopefully reducing the number of instructions. We make sure that
+  // at least one bitcast only has one use, so we don't *increase* the number of
+  // instructions here.
+  Value *X, *Y;
+  if (match(LHS, m_BitCast(m_Value(X))) && match(RHS, m_BitCast(m_Value(Y))) &&
+      X->getType()->isVectorTy() && X->getType() == Y->getType() &&
+      X->getType()->getScalarSizeInBits() ==
+          SVI.getType()->getScalarSizeInBits() &&
+      (LHS->hasOneUse() || RHS->hasOneUse())) {
+    Value *V = Builder.CreateShuffleVector(X, Y, SVI.getShuffleMask(),
+                                           SVI.getName() + ".uncasted");
+    return new BitCastInst(V, SVI.getType());
+  }
+
   ArrayRef<int> Mask = SVI.getShuffleMask();
   Type *Int32Ty = Type::getInt32Ty(SVI.getContext());
 
@@ -2298,7 +2317,6 @@
   // TODO: This could be extended to allow length-changing shuffles.
   //       The transform might also be obsoleted if we allowed canonicalization
   //       of bitcasted shuffles.
-  Value *X;
   if (match(LHS, m_BitCast(m_Value(X))) && match(RHS, m_Undef()) &&
       X->getType()->isVectorTy() && VWidth == LHSWidth) {
     // Try to create a scaled mask constant.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D97397.327126.patch
Type: text/x-patch
Size: 4876 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210301/50177cf9/attachment.bin>


More information about the llvm-commits mailing list