[llvm] feat: fix big endian shuffle vector miscompile (PR #68673)

David Green via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 11 02:55:29 PDT 2023


================
@@ -10914,6 +10914,26 @@ SDValue AArch64TargetLowering::ReconstructShuffle(SDValue Op,
 
   SDValue Shuffle = DAG.getVectorShuffle(ShuffleVT, dl, ShuffleOps[0],
                                          ShuffleOps[1], Mask);
+  if (DAG.getDataLayout().isBigEndian()) {
+    EVT SrcEltTy = ShuffleVT.getVectorElementType();
+    EVT DstEltTy = VT.getVectorElementType();
+    if (SrcEltTy != DstEltTy) {
+      unsigned REVOp = 0;
+      unsigned DstTypeSize = DstEltTy.getFixedSizeInBits();
+      unsigned SrcTypeSize = SrcEltTy.getFixedSizeInBits();
+      if (std::max(DstTypeSize, SrcTypeSize) == 16) {
+        REVOp = AArch64ISD::REV16;
+      } else if (std::max(DstTypeSize, SrcTypeSize) == 32) {
+        REVOp = AArch64ISD::REV32;
+      } else if (std::max(DstTypeSize, SrcTypeSize) == 64) {
+        REVOp = AArch64ISD::REV64;
+      }
+      if (REVOp) {
+        Shuffle = DAG.getNode(REVOp, dl, ShuffleVT, Shuffle);
+      }
+    }
+  }
+  
   SDValue V = DAG.getNode(ISD::BITCAST, dl, VT, Shuffle);
----------------
davemgreen wrote:

BITCAST is defined as a store+load of the data type, so can re-arrange data inside the vector lanes under big endian.
NVCAST is an AArch64 specific node that deliberately doesn't do the same lane interchanging.

So VREV+BITCAST should equal NVCAST (under BE), and I think if this ISD::BITCAST was a AArch64ISD::NVCAST instead then it would handle case you've found, where you've added the REV's (and should maybe optimize better?)

https://github.com/llvm/llvm-project/pull/68673


More information about the llvm-commits mailing list