[llvm] f1dcb9c - [SDAG] neg x with only low bit demanded is x
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 19 15:26:12 PST 2022
Author: Philip Reames
Date: 2022-12-19T15:25:43-08:00
New Revision: f1dcb9c36fe46c97a8f22c8b2544fb25d2e4cb61
URL: https://github.com/llvm/llvm-project/commit/f1dcb9c36fe46c97a8f22c8b2544fb25d2e4cb61
DIFF: https://github.com/llvm/llvm-project/commit/f1dcb9c36fe46c97a8f22c8b2544fb25d2e4cb61.diff
LOG: [SDAG] neg x with only low bit demanded is x
We have a version of this transform in InstCombine, but surprisingly not in SDAG. Even more surprisingly, this benefits RISCV, but no other target. This was surprising enough I double checked my build configuration to make sure all targets were enabled; they appear to be.
Differential Revision: https://reviews.llvm.org/D140324
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
llvm/test/CodeGen/RISCV/alu64.ll
llvm/test/CodeGen/RISCV/bittest.ll
llvm/test/CodeGen/RISCV/forced-atomics.ll
llvm/test/CodeGen/RISCV/fpclamptosat.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index aa7d7296cd65c..dbf318a85e9ed 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -2614,6 +2614,11 @@ bool TargetLowering::SimplifyDemandedBits(
return true;
}
+ // neg x with only low bit demanded is simply x.
+ if (Op.getOpcode() == ISD::SUB && DemandedBits.isOne() &&
+ isa<ConstantSDNode>(Op0) && cast<ConstantSDNode>(Op0)->isZero())
+ return TLO.CombineTo(Op, Op1);
+
// Attempt to avoid multi-use ops if we don't need anything from them.
if (!LoMask.isAllOnes() || !DemandedElts.isAllOnes()) {
SDValue DemandedOp0 = SimplifyMultipleUseDemandedBits(
diff --git a/llvm/test/CodeGen/RISCV/alu64.ll b/llvm/test/CodeGen/RISCV/alu64.ll
index bef2b81b43821..34bcb0b17f710 100644
--- a/llvm/test/CodeGen/RISCV/alu64.ll
+++ b/llvm/test/CodeGen/RISCV/alu64.ll
@@ -59,8 +59,7 @@ define i64 @sltiu(i64 %a) nounwind {
; RV32I-LABEL: sltiu:
; RV32I: # %bb.0:
; RV32I-NEXT: sltiu a0, a0, 3
-; RV32I-NEXT: snez a1, a1
-; RV32I-NEXT: addi a1, a1, -1
+; RV32I-NEXT: seqz a1, a1
; RV32I-NEXT: and a0, a1, a0
; RV32I-NEXT: li a1, 0
; RV32I-NEXT: ret
diff --git a/llvm/test/CodeGen/RISCV/bittest.ll b/llvm/test/CodeGen/RISCV/bittest.ll
index c952c37229006..e129212ee12e0 100644
--- a/llvm/test/CodeGen/RISCV/bittest.ll
+++ b/llvm/test/CodeGen/RISCV/bittest.ll
@@ -301,9 +301,7 @@ define i1 @bittest_constant_by_var_shr_i64(i64 %b) nounwind {
; RV32-NEXT: srl a1, a1, a0
; RV32-NEXT: addi a0, a0, -32
; RV32-NEXT: slti a0, a0, 0
-; RV32-NEXT: neg a0, a0
; RV32-NEXT: and a0, a0, a1
-; RV32-NEXT: andi a0, a0, 1
; RV32-NEXT: ret
;
; RV64I-LABEL: bittest_constant_by_var_shr_i64:
@@ -335,9 +333,7 @@ define i1 @bittest_constant_by_var_shl_i64(i64 %b) nounwind {
; RV32-NEXT: srl a1, a1, a0
; RV32-NEXT: addi a0, a0, -32
; RV32-NEXT: slti a0, a0, 0
-; RV32-NEXT: neg a0, a0
; RV32-NEXT: and a0, a0, a1
-; RV32-NEXT: andi a0, a0, 1
; RV32-NEXT: ret
;
; RV64I-LABEL: bittest_constant_by_var_shl_i64:
diff --git a/llvm/test/CodeGen/RISCV/forced-atomics.ll b/llvm/test/CodeGen/RISCV/forced-atomics.ll
index 4c8176419f729..566b540547905 100644
--- a/llvm/test/CodeGen/RISCV/forced-atomics.ll
+++ b/llvm/test/CodeGen/RISCV/forced-atomics.ll
@@ -2806,8 +2806,7 @@ define i64 @rmw64_umin_seq_cst(ptr %p) nounwind {
; RV32-NEXT: .LBB52_2: # %atomicrmw.start
; RV32-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-NEXT: sltiu a0, a4, 2
-; RV32-NEXT: snez a2, a1
-; RV32-NEXT: addi a2, a2, -1
+; RV32-NEXT: seqz a2, a1
; RV32-NEXT: and a0, a2, a0
; RV32-NEXT: mv a2, a4
; RV32-NEXT: bnez a0, .LBB52_1
diff --git a/llvm/test/CodeGen/RISCV/fpclamptosat.ll b/llvm/test/CodeGen/RISCV/fpclamptosat.ll
index a2718295ae6a9..7eb7e14353329 100644
--- a/llvm/test/CodeGen/RISCV/fpclamptosat.ll
+++ b/llvm/test/CodeGen/RISCV/fpclamptosat.ll
@@ -115,8 +115,7 @@ define i32 @utest_f64i32(double %x) {
; RV32IF-NEXT: .cfi_offset ra, -4
; RV32IF-NEXT: call __fixunsdfdi at plt
; RV32IF-NEXT: sltiu a2, a0, -1
-; RV32IF-NEXT: snez a1, a1
-; RV32IF-NEXT: addi a1, a1, -1
+; RV32IF-NEXT: seqz a1, a1
; RV32IF-NEXT: and a1, a1, a2
; RV32IF-NEXT: addi a1, a1, -1
; RV32IF-NEXT: or a0, a1, a0
@@ -434,8 +433,7 @@ define i32 @utesth_f16i32(half %x) {
; RV32-NEXT: call __extendhfsf2 at plt
; RV32-NEXT: call __fixunssfdi at plt
; RV32-NEXT: sltiu a2, a0, -1
-; RV32-NEXT: snez a1, a1
-; RV32-NEXT: addi a1, a1, -1
+; RV32-NEXT: seqz a1, a1
; RV32-NEXT: and a1, a1, a2
; RV32-NEXT: addi a1, a1, -1
; RV32-NEXT: or a0, a1, a0
@@ -1241,10 +1239,8 @@ define i64 @utest_f64i64(double %x) {
; RV32IF-NEXT: lw a1, 20(sp)
; RV32IF-NEXT: lw a2, 12(sp)
; RV32IF-NEXT: lw a3, 8(sp)
-; RV32IF-NEXT: seqz a4, a0
-; RV32IF-NEXT: snez a5, a1
-; RV32IF-NEXT: addi a5, a5, -1
-; RV32IF-NEXT: and a4, a5, a4
+; RV32IF-NEXT: or a4, a1, a0
+; RV32IF-NEXT: seqz a4, a4
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: or a0, a0, a1
; RV32IF-NEXT: seqz a0, a0
@@ -1283,10 +1279,8 @@ define i64 @utest_f64i64(double %x) {
; RV32IFD-NEXT: lw a1, 20(sp)
; RV32IFD-NEXT: lw a2, 12(sp)
; RV32IFD-NEXT: lw a3, 8(sp)
-; RV32IFD-NEXT: seqz a4, a0
-; RV32IFD-NEXT: snez a5, a1
-; RV32IFD-NEXT: addi a5, a5, -1
-; RV32IFD-NEXT: and a4, a5, a4
+; RV32IFD-NEXT: or a4, a1, a0
+; RV32IFD-NEXT: seqz a4, a4
; RV32IFD-NEXT: xori a0, a0, 1
; RV32IFD-NEXT: or a0, a0, a1
; RV32IFD-NEXT: seqz a0, a0
@@ -1555,10 +1549,8 @@ define i64 @utest_f32i64(float %x) {
; RV32-NEXT: lw a1, 20(sp)
; RV32-NEXT: lw a2, 12(sp)
; RV32-NEXT: lw a3, 8(sp)
-; RV32-NEXT: seqz a4, a0
-; RV32-NEXT: snez a5, a1
-; RV32-NEXT: addi a5, a5, -1
-; RV32-NEXT: and a4, a5, a4
+; RV32-NEXT: or a4, a1, a0
+; RV32-NEXT: seqz a4, a4
; RV32-NEXT: xori a0, a0, 1
; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: seqz a0, a0
@@ -1816,10 +1808,8 @@ define i64 @utesth_f16i64(half %x) {
; RV32-NEXT: lw a1, 20(sp)
; RV32-NEXT: lw a2, 12(sp)
; RV32-NEXT: lw a3, 8(sp)
-; RV32-NEXT: seqz a4, a0
-; RV32-NEXT: snez a5, a1
-; RV32-NEXT: addi a5, a5, -1
-; RV32-NEXT: and a4, a5, a4
+; RV32-NEXT: or a4, a1, a0
+; RV32-NEXT: seqz a4, a4
; RV32-NEXT: xori a0, a0, 1
; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: seqz a0, a0
@@ -3234,11 +3224,9 @@ define i64 @utest_f64i64_mm(double %x) {
; RV32IF-NEXT: lw a1, 20(sp)
; RV32IF-NEXT: lw a2, 12(sp)
; RV32IF-NEXT: lw a3, 8(sp)
-; RV32IF-NEXT: seqz a4, a0
-; RV32IF-NEXT: snez a5, a1
-; RV32IF-NEXT: addi a5, a5, -1
-; RV32IF-NEXT: and a4, a5, a4
-; RV32IF-NEXT: neg a4, a4
+; RV32IF-NEXT: or a4, a1, a0
+; RV32IF-NEXT: snez a4, a4
+; RV32IF-NEXT: addi a4, a4, -1
; RV32IF-NEXT: and a3, a4, a3
; RV32IF-NEXT: xori a0, a0, 1
; RV32IF-NEXT: or a0, a0, a1
@@ -3281,11 +3269,9 @@ define i64 @utest_f64i64_mm(double %x) {
; RV32IFD-NEXT: lw a1, 20(sp)
; RV32IFD-NEXT: lw a2, 12(sp)
; RV32IFD-NEXT: lw a3, 8(sp)
-; RV32IFD-NEXT: seqz a4, a0
-; RV32IFD-NEXT: snez a5, a1
-; RV32IFD-NEXT: addi a5, a5, -1
-; RV32IFD-NEXT: and a4, a5, a4
-; RV32IFD-NEXT: neg a4, a4
+; RV32IFD-NEXT: or a4, a1, a0
+; RV32IFD-NEXT: snez a4, a4
+; RV32IFD-NEXT: addi a4, a4, -1
; RV32IFD-NEXT: and a3, a4, a3
; RV32IFD-NEXT: xori a0, a0, 1
; RV32IFD-NEXT: or a0, a0, a1
@@ -3601,11 +3587,9 @@ define i64 @utest_f32i64_mm(float %x) {
; RV32-NEXT: lw a1, 20(sp)
; RV32-NEXT: lw a2, 12(sp)
; RV32-NEXT: lw a3, 8(sp)
-; RV32-NEXT: seqz a4, a0
-; RV32-NEXT: snez a5, a1
-; RV32-NEXT: addi a5, a5, -1
-; RV32-NEXT: and a4, a5, a4
-; RV32-NEXT: neg a4, a4
+; RV32-NEXT: or a4, a1, a0
+; RV32-NEXT: snez a4, a4
+; RV32-NEXT: addi a4, a4, -1
; RV32-NEXT: and a3, a4, a3
; RV32-NEXT: xori a0, a0, 1
; RV32-NEXT: or a0, a0, a1
@@ -3914,11 +3898,9 @@ define i64 @utesth_f16i64_mm(half %x) {
; RV32-NEXT: lw a1, 20(sp)
; RV32-NEXT: lw a2, 12(sp)
; RV32-NEXT: lw a3, 8(sp)
-; RV32-NEXT: seqz a4, a0
-; RV32-NEXT: snez a5, a1
-; RV32-NEXT: addi a5, a5, -1
-; RV32-NEXT: and a4, a5, a4
-; RV32-NEXT: neg a4, a4
+; RV32-NEXT: or a4, a1, a0
+; RV32-NEXT: snez a4, a4
+; RV32-NEXT: addi a4, a4, -1
; RV32-NEXT: and a3, a4, a3
; RV32-NEXT: xori a0, a0, 1
; RV32-NEXT: or a0, a0, a1
More information about the llvm-commits
mailing list