[llvm] 7ff5148 - [DAGCombine] Support splat_vector nodes in (and (extload)) dagcombine
Bradley Smith via llvm-commits
llvm-commits at lists.llvm.org
Mon May 16 04:25:48 PDT 2022
Author: Bradley Smith
Date: 2022-05-16T11:25:20Z
New Revision: 7ff5148d6454531dd138f6ef5be77d14f732754f
URL: https://github.com/llvm/llvm-project/commit/7ff5148d6454531dd138f6ef5be77d14f732754f
DIFF: https://github.com/llvm/llvm-project/commit/7ff5148d6454531dd138f6ef5be77d14f732754f.diff
LOG: [DAGCombine] Support splat_vector nodes in (and (extload)) dagcombine
Differential Revision: https://reviews.llvm.org/D125367
Added:
llvm/test/CodeGen/AArch64/sve-fold-loadext-and-splat-vector.ll
Modified:
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index cce6cdc24069..ed2b0a8c36d6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -6164,7 +6164,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
// This can be a pure constant or a vector splat, in which case we treat the
// vector as a scalar and use the splat value.
APInt Constant = APInt::getZero(1);
- if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(N1)) {
+ if (const ConstantSDNode *C = isConstOrConstSplat(N1)) {
Constant = C->getAPIntValue();
} else if (BuildVectorSDNode *Vector = dyn_cast<BuildVectorSDNode>(N1)) {
APInt SplatValue, SplatUndef;
diff --git a/llvm/test/CodeGen/AArch64/sve-fold-loadext-and-splat-vector.ll b/llvm/test/CodeGen/AArch64/sve-fold-loadext-and-splat-vector.ll
new file mode 100644
index 000000000000..e532743a8658
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/sve-fold-loadext-and-splat-vector.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s | FileCheck %s
+
+target triple = "aarch64-unknown-linux-gnu"
+
+; Ensure that a no-op 'and' after an extending load gets removed when the and is
+; constructed via a splat_vector node.
+define <vscale x 2 x i64> @fold_loadext_and(ptr %ptr, i32 %needle, <vscale x 2 x i64> %b) #0 {
+; CHECK-LABEL: fold_loadext_and:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.d
+; CHECK-NEXT: ld1w { z0.d }, p0/z, [x0]
+; CHECK-NEXT: ret
+ %load = load <vscale x 2 x i32>, ptr %ptr, align 4
+ %ext = zext <vscale x 2 x i32> %load to <vscale x 2 x i64>
+ %splatinsert = insertelement <vscale x 2 x i64> poison, i64 4294967295, i64 0
+ %splat = shufflevector <vscale x 2 x i64> %splatinsert, <vscale x 2 x i64> poison, <vscale x 2 x i32> zeroinitializer
+ %and = and <vscale x 2 x i64> %ext, %splat
+ ret <vscale x 2 x i64> %and
+}
+
+; Same as above but testing the case we care about. Here the vscale x 2 x i32
+; types get legalized into vscale x 2 x i64 types which introduces the extending
+; load and 'and' nodes similar to the above case.
+define <vscale x 2 x i1> @fold_loadext_and_legalize(ptr %ptr, <vscale x 2 x i32> %a) #0 {
+; CHECK-LABEL: fold_loadext_and_legalize:
+; CHECK: // %bb.0:
+; CHECK-NEXT: ptrue p0.d
+; CHECK-NEXT: and z0.d, z0.d, #0xffffffff
+; CHECK-NEXT: ld1w { z1.d }, p0/z, [x0]
+; CHECK-NEXT: cmpeq p0.d, p0/z, z1.d, z0.d
+; CHECK-NEXT: ret
+ %load = load <vscale x 2 x i32>, ptr %ptr
+ %cmp = icmp eq <vscale x 2 x i32> %load, %a
+ ret <vscale x 2 x i1> %cmp
+}
+
+attributes #0 = { "target-features"="+sve" }
More information about the llvm-commits
mailing list