[llvm] [DAGCombine] Fold (icmp eq/ne (shift X, C), 0) -> (icmp eq/ne X, 0) (PR #88801)
Björn Pettersson via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 15 15:05:31 PDT 2024
https://github.com/bjope updated https://github.com/llvm/llvm-project/pull/88801
>From 0e350c174b69b5094a1deda596f5357c46b80cc2 Mon Sep 17 00:00:00 2001
From: Bjorn Pettersson <bjorn.a.pettersson at ericsson.com>
Date: Mon, 15 Apr 2024 23:51:35 +0200
Subject: [PATCH] [DAGCombine] Fold (icmp eq/ne (shift X, C), 0) -> (icmp eq/ne
X, 0)
Optimize
(icmp eq/ne (shift X, C), 0) -> (icmp eq/ne X, 0)
given that all shifted out bits, as well as shifted in bits, are
zero. Defensively limit this to one-use shifts (haven't really
considered if this can be profitable also when there are multiple uses
of the shift).
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 18 +++++++++
.../CodeGen/ARM/simplifysetcc_narrow_load.ll | 18 ++++-----
llvm/test/CodeGen/Hexagon/isel-memory-vNi1.ll | 37 +++++++++---------
.../RISCV/lack-of-signed-truncation-check.ll | 1 +
llvm/test/CodeGen/RISCV/sextw-removal.ll | 38 +++++++++++--------
.../CodeGen/RISCV/signed-truncation-check.ll | 1 +
6 files changed, 68 insertions(+), 45 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index cbba3a294b3d68..238135101ee8c7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12450,6 +12450,24 @@ SDValue DAGCombiner::visitSETCC(SDNode *N) {
return Combined;
}
+ // Optimize
+ // (icmp eq/ne (shift N00, N01C), 0) -> (icmp eq/ne N00, 0)
+ // If shift is logical and all shifted out bits are known to be zero.
+ if ((Cond == ISD::SETNE || Cond == ISD::SETEQ) && isNullOrNullSplat(N1) &&
+ N0->hasOneUse() &&
+ (N0.getOpcode() == ISD::SHL || N0.getOpcode() == ISD::SRL)) {
+ SDValue N00 = N0.getOperand(0);
+ SDValue N01 = N0.getOperand(1);
+ if (ConstantSDNode *N01C = isConstOrConstSplat(N01)) {
+ KnownBits KnownN00 = DAG.computeKnownBits(N00);
+ if ((N0.getOpcode() == ISD::SHL &&
+ N01C->getAPIntValue().ule(KnownN00.countMinLeadingZeros())) ||
+ (N0.getOpcode() == ISD::SRL &&
+ N01C->getAPIntValue().ule(KnownN00.countMinTrailingZeros())))
+ return DAG.getSetCC(SDLoc(N), VT, N00, N1, Cond);
+ }
+ }
+
// Optimize
// 1) (icmp eq/ne (and X, C0), (shift X, C1))
// or
diff --git a/llvm/test/CodeGen/ARM/simplifysetcc_narrow_load.ll b/llvm/test/CodeGen/ARM/simplifysetcc_narrow_load.ll
index 838da59f9e412c..bad99b5c7d976d 100644
--- a/llvm/test/CodeGen/ARM/simplifysetcc_narrow_load.ll
+++ b/llvm/test/CodeGen/ARM/simplifysetcc_narrow_load.ll
@@ -311,7 +311,7 @@ define i1 @test_48_16_8(ptr %y) {
; CHECK-LE-LABEL: test_48_16_8:
; CHECK-LE: @ %bb.0:
; CHECK-LE-NEXT: ldrh r0, [r0, #1]
-; CHECK-LE-NEXT: lsls r0, r0, #8
+; CHECK-LE-NEXT: cmp r0, #0
; CHECK-LE-NEXT: movne r0, #1
; CHECK-LE-NEXT: mov pc, lr
;
@@ -559,28 +559,28 @@ define i1 @test_24_8_8(ptr %y) {
; CHECK-LE-LABEL: test_24_8_8:
; CHECK-LE: @ %bb.0:
; CHECK-LE-NEXT: ldrb r0, [r0, #1]
-; CHECK-LE-NEXT: lsls r0, r0, #8
+; CHECK-LE-NEXT: cmp r0, #0
; CHECK-LE-NEXT: movne r0, #1
; CHECK-LE-NEXT: mov pc, lr
;
; CHECK-V7-LE-LABEL: test_24_8_8:
; CHECK-V7-LE: @ %bb.0:
; CHECK-V7-LE-NEXT: ldrb r0, [r0, #1]
-; CHECK-V7-LE-NEXT: lsls r0, r0, #8
+; CHECK-V7-LE-NEXT: cmp r0, #0
; CHECK-V7-LE-NEXT: movwne r0, #1
; CHECK-V7-LE-NEXT: bx lr
;
; CHECK-BE-LABEL: test_24_8_8:
; CHECK-BE: @ %bb.0:
; CHECK-BE-NEXT: ldrb r0, [r0, #1]
-; CHECK-BE-NEXT: lsls r0, r0, #8
+; CHECK-BE-NEXT: cmp r0, #0
; CHECK-BE-NEXT: movne r0, #1
; CHECK-BE-NEXT: mov pc, lr
;
; CHECK-V7-BE-LABEL: test_24_8_8:
; CHECK-V7-BE: @ %bb.0:
; CHECK-V7-BE-NEXT: ldrb r0, [r0, #1]
-; CHECK-V7-BE-NEXT: lsls r0, r0, #8
+; CHECK-V7-BE-NEXT: cmp r0, #0
; CHECK-V7-BE-NEXT: movwne r0, #1
; CHECK-V7-BE-NEXT: bx lr
%a = load i24, ptr %y
@@ -633,28 +633,28 @@ define i1 @test_24_8_16(ptr %y) {
; CHECK-LE-LABEL: test_24_8_16:
; CHECK-LE: @ %bb.0:
; CHECK-LE-NEXT: ldrb r0, [r0, #2]
-; CHECK-LE-NEXT: lsls r0, r0, #16
+; CHECK-LE-NEXT: cmp r0, #0
; CHECK-LE-NEXT: movne r0, #1
; CHECK-LE-NEXT: mov pc, lr
;
; CHECK-V7-LE-LABEL: test_24_8_16:
; CHECK-V7-LE: @ %bb.0:
; CHECK-V7-LE-NEXT: ldrb r0, [r0, #2]
-; CHECK-V7-LE-NEXT: lsls r0, r0, #16
+; CHECK-V7-LE-NEXT: cmp r0, #0
; CHECK-V7-LE-NEXT: movwne r0, #1
; CHECK-V7-LE-NEXT: bx lr
;
; CHECK-BE-LABEL: test_24_8_16:
; CHECK-BE: @ %bb.0:
; CHECK-BE-NEXT: ldrb r0, [r0]
-; CHECK-BE-NEXT: lsls r0, r0, #16
+; CHECK-BE-NEXT: cmp r0, #0
; CHECK-BE-NEXT: movne r0, #1
; CHECK-BE-NEXT: mov pc, lr
;
; CHECK-V7-BE-LABEL: test_24_8_16:
; CHECK-V7-BE: @ %bb.0:
; CHECK-V7-BE-NEXT: ldrb r0, [r0]
-; CHECK-V7-BE-NEXT: lsls r0, r0, #16
+; CHECK-V7-BE-NEXT: cmp r0, #0
; CHECK-V7-BE-NEXT: movwne r0, #1
; CHECK-V7-BE-NEXT: bx lr
%a = load i24, ptr %y
diff --git a/llvm/test/CodeGen/Hexagon/isel-memory-vNi1.ll b/llvm/test/CodeGen/Hexagon/isel-memory-vNi1.ll
index 2eecfa9f47f176..9df3289a3f589a 100644
--- a/llvm/test/CodeGen/Hexagon/isel-memory-vNi1.ll
+++ b/llvm/test/CodeGen/Hexagon/isel-memory-vNi1.ll
@@ -173,64 +173,61 @@ define void @f6(ptr %a0, i16 %a1) #0 {
; CHECK-LABEL: f6:
; CHECK: // %bb.0: // %b0
; CHECK-NEXT: {
-; CHECK-NEXT: r2 = extractu(r1,#8,#8)
-; CHECK-NEXT: }
-; CHECK-NEXT: {
-; CHECK-NEXT: r3 = #255
+; CHECK-NEXT: r2 = #255
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: p1 = !bitsclr(r1,r3)
+; CHECK-NEXT: r3 = ##65280
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: p0 = cmp.eq(r2,#0)
+; CHECK-NEXT: p1 = !bitsclr(r1,r2)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: if (p0) r2 = #0
+; CHECK-NEXT: p0 = !bitsclr(r1,r3)
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: r1 = mux(p1,#8,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r3 = mux(p1,#2,#0)
+; CHECK-NEXT: r2 = mux(p1,#2,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r5 = setbit(r1,#2)
+; CHECK-NEXT: r3 = mux(p0,##128,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r6 = setbit(r3,#0)
+; CHECK-NEXT: r4 = mux(p0,#32,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: if (!p0) r2 = #128
+; CHECK-NEXT: r5 = setbit(r1,#2)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r4 = mux(p0,#0,#32)
+; CHECK-NEXT: r6 = setbit(r2,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: if (!p1) r5 = add(r1,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: if (!p1) r6 = add(r3,#0)
+; CHECK-NEXT: r1 = setbit(r3,#6)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r1 = setbit(r2,#6)
+; CHECK-NEXT: if (!p1) r6 = add(r2,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r3 = setbit(r4,#4)
+; CHECK-NEXT: r2 = setbit(r4,#4)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r5 = or(r6,r5)
+; CHECK-NEXT: if (!p0) r2 = add(r4,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: if (!p0) r2 = add(r1,#0)
+; CHECK-NEXT: if (!p0) r1 = add(r3,#0)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: if (!p0) r4 = add(r3,#0)
+; CHECK-NEXT: r4 = or(r6,r5)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: r5 |= or(r4,r2)
+; CHECK-NEXT: r4 |= or(r2,r1)
; CHECK-NEXT: }
; CHECK-NEXT: {
-; CHECK-NEXT: memb(r0+#0) = r5
+; CHECK-NEXT: memb(r0+#0) = r4
; CHECK-NEXT: }
; CHECK-NEXT: {
; CHECK-NEXT: jumpr r31
diff --git a/llvm/test/CodeGen/RISCV/lack-of-signed-truncation-check.ll b/llvm/test/CodeGen/RISCV/lack-of-signed-truncation-check.ll
index 6e3a50542939f1..abfa1d3d3f06cb 100644
--- a/llvm/test/CodeGen/RISCV/lack-of-signed-truncation-check.ll
+++ b/llvm/test/CodeGen/RISCV/lack-of-signed-truncation-check.ll
@@ -534,6 +534,7 @@ define i1 @add_ugecmp_i32_i16(i32 %x) nounwind {
; RV64I-NEXT: lui a1, 8
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: srliw a0, a0, 16
+; RV64I-NEXT: slli a0, a0, 16
; RV64I-NEXT: snez a0, a0
; RV64I-NEXT: ret
;
diff --git a/llvm/test/CodeGen/RISCV/sextw-removal.ll b/llvm/test/CodeGen/RISCV/sextw-removal.ll
index f707cb31e3eced..dc5ff5c8081bfa 100644
--- a/llvm/test/CodeGen/RISCV/sextw-removal.ll
+++ b/llvm/test/CodeGen/RISCV/sextw-removal.ll
@@ -1034,31 +1034,34 @@ define signext i32 @bug(i32 signext %x) {
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: beqz a0, .LBB18_4
; CHECK-NEXT: # %bb.1: # %if.end
-; CHECK-NEXT: srliw a2, a0, 16
-; CHECK-NEXT: seqz a1, a2
+; CHECK-NEXT: srliw a3, a0, 16
+; CHECK-NEXT: seqz a1, a3
; CHECK-NEXT: slli a1, a1, 4
; CHECK-NEXT: sllw a1, a0, a1
+; CHECK-NEXT: srliw a2, a1, 24
+; CHECK-NEXT: slli a2, a2, 24
; CHECK-NEXT: li a0, 16
-; CHECK-NEXT: beqz a2, .LBB18_3
+; CHECK-NEXT: beqz a3, .LBB18_3
; CHECK-NEXT: # %bb.2: # %if.end
; CHECK-NEXT: li a0, 32
; CHECK-NEXT: .LBB18_3: # %if.end
-; CHECK-NEXT: srliw a2, a1, 24
; CHECK-NEXT: seqz a2, a2
; CHECK-NEXT: slli a3, a2, 3
; CHECK-NEXT: sllw a1, a1, a3
+; CHECK-NEXT: srliw a3, a1, 28
+; CHECK-NEXT: slli a3, a3, 28
; CHECK-NEXT: neg a2, a2
; CHECK-NEXT: andi a2, a2, -8
; CHECK-NEXT: add a0, a0, a2
-; CHECK-NEXT: srliw a2, a1, 28
-; CHECK-NEXT: seqz a2, a2
+; CHECK-NEXT: seqz a2, a3
; CHECK-NEXT: slli a3, a2, 2
; CHECK-NEXT: sllw a1, a1, a3
+; CHECK-NEXT: srliw a3, a1, 30
+; CHECK-NEXT: slli a3, a3, 30
; CHECK-NEXT: neg a2, a2
; CHECK-NEXT: andi a2, a2, -4
; CHECK-NEXT: add a0, a0, a2
-; CHECK-NEXT: srliw a2, a1, 30
-; CHECK-NEXT: seqz a2, a2
+; CHECK-NEXT: seqz a2, a3
; CHECK-NEXT: slli a3, a2, 1
; CHECK-NEXT: sllw a1, a1, a3
; CHECK-NEXT: neg a2, a2
@@ -1074,31 +1077,34 @@ define signext i32 @bug(i32 signext %x) {
; NOREMOVAL: # %bb.0: # %entry
; NOREMOVAL-NEXT: beqz a0, .LBB18_4
; NOREMOVAL-NEXT: # %bb.1: # %if.end
-; NOREMOVAL-NEXT: srliw a2, a0, 16
-; NOREMOVAL-NEXT: seqz a1, a2
+; NOREMOVAL-NEXT: srliw a3, a0, 16
+; NOREMOVAL-NEXT: seqz a1, a3
; NOREMOVAL-NEXT: slli a1, a1, 4
; NOREMOVAL-NEXT: sllw a1, a0, a1
+; NOREMOVAL-NEXT: srliw a2, a1, 24
+; NOREMOVAL-NEXT: slli a2, a2, 24
; NOREMOVAL-NEXT: li a0, 16
-; NOREMOVAL-NEXT: beqz a2, .LBB18_3
+; NOREMOVAL-NEXT: beqz a3, .LBB18_3
; NOREMOVAL-NEXT: # %bb.2: # %if.end
; NOREMOVAL-NEXT: li a0, 32
; NOREMOVAL-NEXT: .LBB18_3: # %if.end
-; NOREMOVAL-NEXT: srliw a2, a1, 24
; NOREMOVAL-NEXT: seqz a2, a2
; NOREMOVAL-NEXT: slli a3, a2, 3
; NOREMOVAL-NEXT: sllw a1, a1, a3
+; NOREMOVAL-NEXT: srliw a3, a1, 28
+; NOREMOVAL-NEXT: slli a3, a3, 28
; NOREMOVAL-NEXT: neg a2, a2
; NOREMOVAL-NEXT: andi a2, a2, -8
; NOREMOVAL-NEXT: add a0, a0, a2
-; NOREMOVAL-NEXT: srliw a2, a1, 28
-; NOREMOVAL-NEXT: seqz a2, a2
+; NOREMOVAL-NEXT: seqz a2, a3
; NOREMOVAL-NEXT: slli a3, a2, 2
; NOREMOVAL-NEXT: sllw a1, a1, a3
+; NOREMOVAL-NEXT: srliw a3, a1, 30
+; NOREMOVAL-NEXT: slli a3, a3, 30
; NOREMOVAL-NEXT: neg a2, a2
; NOREMOVAL-NEXT: andi a2, a2, -4
; NOREMOVAL-NEXT: add a0, a0, a2
-; NOREMOVAL-NEXT: srliw a2, a1, 30
-; NOREMOVAL-NEXT: seqz a2, a2
+; NOREMOVAL-NEXT: seqz a2, a3
; NOREMOVAL-NEXT: slli a3, a2, 1
; NOREMOVAL-NEXT: sllw a1, a1, a3
; NOREMOVAL-NEXT: neg a2, a2
diff --git a/llvm/test/CodeGen/RISCV/signed-truncation-check.ll b/llvm/test/CodeGen/RISCV/signed-truncation-check.ll
index de36bcdb910609..c5e2c23169df0c 100644
--- a/llvm/test/CodeGen/RISCV/signed-truncation-check.ll
+++ b/llvm/test/CodeGen/RISCV/signed-truncation-check.ll
@@ -586,6 +586,7 @@ define i1 @add_ultcmp_i32_i16(i32 %x) nounwind {
; RV64I-NEXT: lui a1, 8
; RV64I-NEXT: add a0, a0, a1
; RV64I-NEXT: srliw a0, a0, 16
+; RV64I-NEXT: slli a0, a0, 16
; RV64I-NEXT: seqz a0, a0
; RV64I-NEXT: ret
;
More information about the llvm-commits
mailing list