[llvm] 87bc91d - [PowerPC] Fix shuffle combine with undef elements (#77787)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 15 01:12:37 PST 2024


Author: Nikita Popov
Date: 2024-01-15T10:12:33+01:00
New Revision: 87bc91d4259c53d98d8c5c6b7c622f65ddb4c62a

URL: https://github.com/llvm/llvm-project/commit/87bc91d4259c53d98d8c5c6b7c622f65ddb4c62a
DIFF: https://github.com/llvm/llvm-project/commit/87bc91d4259c53d98d8c5c6b7c622f65ddb4c62a.diff

LOG: [PowerPC] Fix shuffle combine with undef elements (#77787)

This custom DAG combine works on a shuffle where one source vector is a
zero splat, which means we can adjust the shuffle indices to refer to
any element of the splat -- as long as we stay in the same vector.

In the case where an undef (-1) index into the non-splat vector was
used, we ended up adjusting the splat index to -1+NumElements, which
points into the wrong vector.

Fix this by using the first element from the splat if the other one is undef.
There are four cases this theoretically affects, but in practice I only
managed to demonstrate a miscompile with one of them. I think two of
theses are effectively dead due to the operand canonicalization at the
start of the transform.

Fixes https://github.com/llvm/llvm-project/issues/77748.

Added: 
    

Modified: 
    llvm/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/test/CodeGen/PowerPC/pr77748.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 4e164fda1d8dd8..aec58d1c0dcb9f 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -15430,7 +15430,8 @@ SDValue PPCTargetLowering::combineVectorShuffle(ShuffleVectorSDNode *SVN,
       for (int i = 1, e = Mask.size(); i < e; i += 2) {
         if (ShuffV[i] < 0)
           continue;
-        ShuffV[i] = (ShuffV[i - 1] + NumElts);
+        // If element from non-splat is undef, pick first element from splat.
+        ShuffV[i] = (ShuffV[i - 1] >= 0 ? ShuffV[i - 1] : 0) + NumElts;
       }
     // Example (odd elements from first vector):
     // vector_shuffle<16,0,17,1,18,2,19,3,20,4,21,5,22,6,23,7> t1, <zero>
@@ -15438,7 +15439,8 @@ SDValue PPCTargetLowering::combineVectorShuffle(ShuffleVectorSDNode *SVN,
       for (int i = 0, e = Mask.size(); i < e; i += 2) {
         if (ShuffV[i] < 0)
           continue;
-        ShuffV[i] = (ShuffV[i + 1] + NumElts);
+        // If element from non-splat is undef, pick first element from splat.
+        ShuffV[i] = (ShuffV[i + 1] >= 0 ? ShuffV[i + 1] : 0) + NumElts;
       }
   } else {
     // Example (even elements from first vector):
@@ -15447,7 +15449,8 @@ SDValue PPCTargetLowering::combineVectorShuffle(ShuffleVectorSDNode *SVN,
       for (int i = 0, e = Mask.size(); i < e; i += 2) {
         if (ShuffV[i] < 0)
           continue;
-        ShuffV[i] = ShuffV[i + 1] - NumElts;
+        // If element from non-splat is undef, pick first element from splat.
+        ShuffV[i] = ShuffV[i + 1] >= 0 ? ShuffV[i + 1] - NumElts : 0;
       }
     // Example (odd elements from first vector):
     // vector_shuffle<16,0,17,1,18,2,19,3,20,4,21,5,22,6,23,7> <zero>, t1
@@ -15455,7 +15458,8 @@ SDValue PPCTargetLowering::combineVectorShuffle(ShuffleVectorSDNode *SVN,
       for (int i = 1, e = Mask.size(); i < e; i += 2) {
         if (ShuffV[i] < 0)
           continue;
-        ShuffV[i] = ShuffV[i - 1] - NumElts;
+        // If element from non-splat is undef, pick first element from splat.
+        ShuffV[i] = ShuffV[i - 1] >= 0 ? ShuffV[i - 1] - NumElts : 0;
       }
   }
 

diff  --git a/llvm/test/CodeGen/PowerPC/pr77748.ll b/llvm/test/CodeGen/PowerPC/pr77748.ll
index 661ea29445a891..d4928f95002c1f 100644
--- a/llvm/test/CodeGen/PowerPC/pr77748.ll
+++ b/llvm/test/CodeGen/PowerPC/pr77748.ll
@@ -2,8 +2,6 @@
 ; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -mattr=+altivec -ppc-asm-full-reg-names < %s | FileCheck %s --check-prefixes=LE
 ; RUN: llc -mtriple=powerpc64-unknown-linux-gnu -mattr=+altivec,+direct-move -ppc-asm-full-reg-names < %s | FileCheck %s --check-prefixes=BE
 
-; FIXME: This is miscompile.
-
 ; LE-LABEL: .LCPI0_0:
 ; LE-NEXT: 	.byte	31
 ; LE-NEXT: 	.byte	15
@@ -14,13 +12,13 @@
 ; LE-NEXT: 	.byte	28
 ; LE-NEXT: 	.byte	12
 ; LE-NEXT: 	.byte	31
-; LE-NEXT: 	.byte	16
+; LE-NEXT: 	.byte	15
 ; LE-NEXT: 	.byte	31
-; LE-NEXT: 	.byte	16
+; LE-NEXT: 	.byte	15
 ; LE-NEXT: 	.byte	31
-; LE-NEXT: 	.byte	16
+; LE-NEXT: 	.byte	15
 ; LE-NEXT: 	.byte	31
-; LE-NEXT: 	.byte	16
+; LE-NEXT: 	.byte	15
 
 ; BE-LABEL: .LCPI0_0:
 ; BE-NEXT: 	.byte	0


        


More information about the llvm-commits mailing list