[llvm] 6a7e958 - [InstCombine] try to reduce more shuffles with bitcasted operand

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 14 12:04:07 PDT 2020


Author: Sanjay Patel
Date: 2020-04-14T15:03:59-04:00
New Revision: 6a7e958a423ed1d33b42cfb10563a46ccc07f44d

URL: https://github.com/llvm/llvm-project/commit/6a7e958a423ed1d33b42cfb10563a46ccc07f44d
DIFF: https://github.com/llvm/llvm-project/commit/6a7e958a423ed1d33b42cfb10563a46ccc07f44d.diff

LOG: [InstCombine] try to reduce more shuffles with bitcasted operand

This is the widen mask element sibling to D76844.

shuf (bitcast X), undef, Mask --> bitcast X'

http://volta.cs.utah.edu:8080/z/4dt3V8

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
    llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index cf3b9dd84a95..b1e41e744f33 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -1955,26 +1955,31 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
   // Peek through a bitcasted shuffle operand by scaling the mask. If the
   // simulated shuffle can simplify, then this shuffle is unnecessary:
   // shuf (bitcast X), undef, Mask --> bitcast X'
-  // TODO: This could be extended to allow length-changing shuffles and/or casts
-  //       to narrower elements. The transform might also be obsoleted if we
-  //       allowed canonicalization of bitcasted shuffles.
+  // 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 &&
-      cast<VectorType>(X->getType())->getNumElements() >= VWidth) {
-    // Create the scaled mask constant.
+      X->getType()->isVectorTy() && VWidth == LHSWidth) {
+    // Try to create a scaled mask constant.
     auto *XType = cast<VectorType>(X->getType());
     unsigned XNumElts = XType->getNumElements();
-    assert(XNumElts % VWidth == 0 && "Unexpected vector bitcast");
-    unsigned ScaleFactor = XNumElts / VWidth;
     SmallVector<int, 16> ScaledMask;
-    narrowShuffleMaskElts(ScaleFactor, Mask, ScaledMask);
-
-    // If the shuffled source vector simplifies, cast that value to this
-    // shuffle's type.
-    if (auto *V = SimplifyShuffleVectorInst(X, UndefValue::get(XType),
-                                            ScaledMask, XType, ShufQuery))
-      return BitCastInst::Create(Instruction::BitCast, V, SVI.getType());
+    if (XNumElts >= VWidth) {
+      assert(XNumElts % VWidth == 0 && "Unexpected vector bitcast");
+      narrowShuffleMaskElts(XNumElts / VWidth, Mask, ScaledMask);
+    } else {
+      assert(VWidth % XNumElts == 0 && "Unexpected vector bitcast");
+      if (!widenShuffleMaskElts(VWidth / XNumElts, Mask, ScaledMask))
+        ScaledMask.clear();
+    }
+    if (!ScaledMask.empty()) {
+      // If the shuffled source vector simplifies, cast that value to this
+      // shuffle's type.
+      if (auto *V = SimplifyShuffleVectorInst(X, UndefValue::get(XType),
+                                              ScaledMask, XType, ShufQuery))
+        return BitCastInst::Create(Instruction::BitCast, V, SVI.getType());
+    }
   }
 
   if (LHS == RHS) {

diff  --git a/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll b/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll
index 63f7472ff20e..6dbc384db1c0 100644
--- a/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll
+++ b/llvm/test/Transforms/InstCombine/shufflevec-bitcast.ll
@@ -94,13 +94,12 @@ define <5 x i16> @splat_bitcast_operand_change_type(<8 x i8> %x) {
   ret <5 x i16> %s2
 }
 
-; TODO: Could allow fold for cast to narrow element.
+; Shuffle-of-bitcast-splat --> splat-bitcast
 
 define <4 x i16> @splat_bitcast_operand_wider_src_elt(<2 x i32> %x) {
 ; CHECK-LABEL: @splat_bitcast_operand_wider_src_elt(
-; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> undef, <2 x i32> <i32 1, i32 undef>
-; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x i32> [[S1]] to <4 x i16>
-; CHECK-NEXT:    [[S2:%.*]] = shufflevector <4 x i16> [[BC]], <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> undef, <2 x i32> <i32 1, i32 1>
+; CHECK-NEXT:    [[S2:%.*]] = bitcast <2 x i32> [[S1]] to <4 x i16>
 ; CHECK-NEXT:    ret <4 x i16> [[S2]]
 ;
   %s1 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 1>
@@ -109,12 +108,14 @@ define <4 x i16> @splat_bitcast_operand_wider_src_elt(<2 x i32> %x) {
   ret <4 x i16> %s2
 }
 
+; Shuffle-of-bitcast-splat --> splat-bitcast
+
 define <4 x i16> @splat_bitcast_operand_wider_src_elt_uses(<2 x i32> %x) {
 ; CHECK-LABEL: @splat_bitcast_operand_wider_src_elt_uses(
 ; CHECK-NEXT:    [[S1:%.*]] = shufflevector <2 x i32> [[X:%.*]], <2 x i32> undef, <2 x i32> <i32 1, i32 1>
 ; CHECK-NEXT:    [[BC:%.*]] = bitcast <2 x i32> [[S1]] to <4 x i16>
 ; CHECK-NEXT:    call void @use(<4 x i16> [[BC]])
-; CHECK-NEXT:    [[S2:%.*]] = shufflevector <4 x i16> [[BC]], <4 x i16> undef, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+; CHECK-NEXT:    [[S2:%.*]] = bitcast <2 x i32> [[S1]] to <4 x i16>
 ; CHECK-NEXT:    ret <4 x i16> [[S2]]
 ;
   %s1 = shufflevector <2 x i32> %x, <2 x i32> undef, <2 x i32> <i32 1, i32 1>
@@ -128,9 +129,7 @@ define <4 x i16> @splat_bitcast_operand_wider_src_elt_uses(<2 x i32> %x) {
 
 define <16 x i8> @shuf_bitcast_operand_wider_src(<4 x i32> %x) {
 ; CHECK-LABEL: @shuf_bitcast_operand_wider_src(
-; CHECK-NEXT:    [[S1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
-; CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i32> [[S1]] to <16 x i8>
-; CHECK-NEXT:    [[S2:%.*]] = shufflevector <16 x i8> [[BC]], <16 x i8> undef, <16 x i32> <i32 12, i32 13, i32 14, i32 15, i32 8, i32 9, i32 10, i32 11, i32 4, i32 5, i32 6, i32 7, i32 0, i32 1, i32 2, i32 3>
+; CHECK-NEXT:    [[S2:%.*]] = bitcast <4 x i32> [[X:%.*]] to <16 x i8>
 ; CHECK-NEXT:    ret <16 x i8> [[S2]]
 ;
   %s1 = shufflevector <4 x i32> %x, <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
@@ -139,6 +138,8 @@ define <16 x i8> @shuf_bitcast_operand_wider_src(<4 x i32> %x) {
   ret <16 x i8> %s2
 }
 
+; Negative test - the 2nd mask can't be widened
+
 define <16 x i8> @shuf_bitcast_operand_cannot_widen(<4 x i32> %x) {
 ; CHECK-LABEL: @shuf_bitcast_operand_cannot_widen(
 ; CHECK-NEXT:    [[S1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
@@ -152,6 +153,8 @@ define <16 x i8> @shuf_bitcast_operand_cannot_widen(<4 x i32> %x) {
   ret <16 x i8> %s2
 }
 
+; Negative test - the 2nd mask can't be widened
+
 define <16 x i8> @shuf_bitcast_operand_cannot_widen_undef(<4 x i32> %x) {
 ; CHECK-LABEL: @shuf_bitcast_operand_cannot_widen_undef(
 ; CHECK-NEXT:    [[S1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> <i32 3, i32 2, i32 1, i32 0>


        


More information about the llvm-commits mailing list