[llvm-branch-commits] [llvm] 65d2e9b - [DAGCombiner] Extend visitAND to include EXTRACT_SUBVECTOR

Tobias Hieta via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Aug 9 04:32:44 PDT 2022


Author: David Sherwood
Date: 2022-08-09T13:30:00+02:00
New Revision: 65d2e9b4e123d9ea472f0f37a5ca64d9ca01bde1

URL: https://github.com/llvm/llvm-project/commit/65d2e9b4e123d9ea472f0f37a5ca64d9ca01bde1
DIFF: https://github.com/llvm/llvm-project/commit/65d2e9b4e123d9ea472f0f37a5ca64d9ca01bde1.diff

LOG: [DAGCombiner] Extend visitAND to include EXTRACT_SUBVECTOR

Eliminate an AND by redefining an anyext|sext|zext.

     (and (extract_subvector (anyext|sext|zext v) _) iN_mask)
  => (extract_subvector (zeroext_iN v))

Differential Revision: https://reviews.llvm.org/D130782

(cherry picked from commit 41119a0f520d07a438f7434f17ce63cc3a942d1b)

Added: 
    llvm/test/CodeGen/AArch64/extract-subvec-combine.ll

Modified: 
    llvm/include/llvm/CodeGen/ISDOpcodes.h
    llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/test/CodeGen/AArch64/vector-fcvt.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/CodeGen/ISDOpcodes.h b/llvm/include/llvm/CodeGen/ISDOpcodes.h
index e907301404067..b7f6de40266e2 100644
--- a/llvm/include/llvm/CodeGen/ISDOpcodes.h
+++ b/llvm/include/llvm/CodeGen/ISDOpcodes.h
@@ -1486,6 +1486,11 @@ inline unsigned getUnorderedFlavor(CondCode Cond) {
 /// SetCC operation.
 CondCode getSetCCInverse(CondCode Operation, EVT Type);
 
+inline bool isExtOpcode(unsigned Opcode) {
+  return Opcode == ISD::ANY_EXTEND || Opcode == ISD::ZERO_EXTEND ||
+         Opcode == ISD::SIGN_EXTEND;
+}
+
 namespace GlobalISel {
 /// Return the operation corresponding to !(X op Y), where 'op' is a valid
 /// SetCC operation. The U bit of the condition code has 
diff erent meanings

diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a367ea51be303..154a3ef63613d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6353,6 +6353,24 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
     }
   }
 
+  if (N0.getOpcode() == ISD::EXTRACT_SUBVECTOR && N0.hasOneUse() && N1C &&
+      ISD::isExtOpcode(N0.getOperand(0).getOpcode())) {
+    SDValue Ext = N0.getOperand(0);
+    EVT ExtVT = Ext->getValueType(0);
+    SDValue Extendee = Ext->getOperand(0);
+
+    unsigned ScalarWidth = Extendee.getValueType().getScalarSizeInBits();
+    if (N1C->getAPIntValue().isMask(ScalarWidth)) {
+      //    (and (extract_subvector (zext|anyext|sext v) _) iN_mask)
+      // => (extract_subvector (iN_zeroext v))
+      SDValue ZeroExtExtendee =
+          DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), ExtVT, Extendee);
+
+      return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SDLoc(N), VT, ZeroExtExtendee,
+                         N0.getOperand(1));
+    }
+  }
+
   // fold (and (masked_gather x)) -> (zext_masked_gather x)
   if (auto *GN0 = dyn_cast<MaskedGatherSDNode>(N0)) {
     EVT MemVT = GN0->getMemoryVT();

diff  --git a/llvm/test/CodeGen/AArch64/extract-subvec-combine.ll b/llvm/test/CodeGen/AArch64/extract-subvec-combine.ll
new file mode 100644
index 0000000000000..c4d77632939e4
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/extract-subvec-combine.ll
@@ -0,0 +1,55 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK
+
+define <2 x i32> @and_extract_zext_idx0(<4 x i16> %vec) nounwind {
+; CHECK-LABEL: and_extract_zext_idx0:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ushll v0.4s, v0.4h, #0
+; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT:    ret
+  %zext = zext <4 x i16> %vec to <4 x i32>
+  %extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 0)
+  %and = and <2 x i32> %extract, <i32 65535, i32 65535>
+  ret <2 x i32> %and
+}
+
+define <4 x i16> @and_extract_sext_idx0(<8 x i8> %vec) nounwind {
+; CHECK-LABEL: and_extract_sext_idx0:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ushll v0.8h, v0.8b, #0
+; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT:    ret
+  %sext = sext <8 x i8> %vec to <8 x i16>
+  %extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 0)
+  %and = and <4 x i16> %extract, <i16 255, i16 255, i16 255, i16 255>
+  ret <4 x i16> %and
+}
+
+define <2 x i32> @and_extract_zext_idx2(<4 x i16> %vec) nounwind {
+; CHECK-LABEL: and_extract_zext_idx2:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ushll v0.4s, v0.4h, #0
+; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT:    ret
+  %zext = zext <4 x i16> %vec to <4 x i32>
+  %extract = call <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32> %zext, i64 2)
+  %and = and <2 x i32> %extract, <i32 65535, i32 65535>
+  ret <2 x i32> %and
+}
+
+define <4 x i16> @and_extract_sext_idx4(<8 x i8> %vec) nounwind {
+; CHECK-LABEL: and_extract_sext_idx4:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    ushll v0.8h, v0.8b, #0
+; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
+; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
+; CHECK-NEXT:    ret
+  %sext = sext <8 x i8> %vec to <8 x i16>
+  %extract = call <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16> %sext, i64 4)
+  %and = and <4 x i16> %extract, <i16 255, i16 255, i16 255, i16 255>
+  ret <4 x i16> %and
+}
+
+declare <2 x i32> @llvm.vector.extract.v2i32.v4i32(<4 x i32>, i64)
+declare <4 x i16> @llvm.vector.extract.v4i16.v8i16(<8 x i16>, i64)

diff  --git a/llvm/test/CodeGen/AArch64/vector-fcvt.ll b/llvm/test/CodeGen/AArch64/vector-fcvt.ll
index 7a47a3e832b9a..7d4a9ee1c8db1 100644
--- a/llvm/test/CodeGen/AArch64/vector-fcvt.ll
+++ b/llvm/test/CodeGen/AArch64/vector-fcvt.ll
@@ -503,23 +503,16 @@ define <16 x double> @uitofp_v16i8_double(<16 x i8> %a) {
 define <8 x double> @uitofp_i16_double(<8 x i16> %a) {
 ; CHECK-LABEL: uitofp_i16_double:
 ; CHECK:       // %bb.0:
-; CHECK-NEXT:    movi d1, #0x00ffff0000ffff
-; CHECK-NEXT:    ushll2 v2.4s, v0.8h, #0
+; CHECK-NEXT:    ushll2 v1.4s, v0.8h, #0
 ; CHECK-NEXT:    ushll v0.4s, v0.4h, #0
-; CHECK-NEXT:    and v3.8b, v2.8b, v1.8b
-; CHECK-NEXT:    and v4.8b, v0.8b, v1.8b
-; CHECK-NEXT:    ext v2.16b, v2.16b, v2.16b, #8
-; CHECK-NEXT:    ext v0.16b, v0.16b, v0.16b, #8
-; CHECK-NEXT:    ushll v3.2d, v3.2s, #0
-; CHECK-NEXT:    ushll v4.2d, v4.2s, #0
-; CHECK-NEXT:    and v2.8b, v2.8b, v1.8b
-; CHECK-NEXT:    and v0.8b, v0.8b, v1.8b
-; CHECK-NEXT:    ushll v5.2d, v2.2s, #0
-; CHECK-NEXT:    ucvtf v2.2d, v3.2d
-; CHECK-NEXT:    ushll v1.2d, v0.2s, #0
-; CHECK-NEXT:    ucvtf v0.2d, v4.2d
-; CHECK-NEXT:    ucvtf v1.2d, v1.2d
-; CHECK-NEXT:    ucvtf v3.2d, v5.2d
+; CHECK-NEXT:    ushll2 v2.2d, v1.4s, #0
+; CHECK-NEXT:    ushll2 v3.2d, v0.4s, #0
+; CHECK-NEXT:    ushll v4.2d, v1.2s, #0
+; CHECK-NEXT:    ushll v0.2d, v0.2s, #0
+; CHECK-NEXT:    ucvtf v1.2d, v3.2d
+; CHECK-NEXT:    ucvtf v0.2d, v0.2d
+; CHECK-NEXT:    ucvtf v3.2d, v2.2d
+; CHECK-NEXT:    ucvtf v2.2d, v4.2d
 ; CHECK-NEXT:    ret
   %1 = uitofp <8 x i16> %a to <8 x double>
   ret <8 x double> %1


        


More information about the llvm-branch-commits mailing list