[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