[PATCH] D155328: [RISCV] Add a DAG combine for (czero_eq X, (xor Y, 1)) -> (czero_ne X, Y) if Y is 0 or 1.

Mikhail Gudim via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 14 14:55:17 PDT 2023


mgudim added a comment.

In D155328#4502297 <https://reviews.llvm.org/D155328#4502297>, @craig.topper wrote:

> In D155328#4502274 <https://reviews.llvm.org/D155328#4502274>, @mgudim wrote:
>
>> LGTM, but it seems weird to me that we have to re-implement such basic optimisations instead of generic code doing this.  @craig.topper @asb I know I asked this is the call, but I still don't understand why we emit target-specific node for SELECT so early?
>
> There isn’t a generic combine for this on select after type legalization. It depends on getBooleanContents to know the value for true. So I think it only exists for i1.

Let's pretend that "SELECT" was legal. (I commented out  `setOperationAction(ISD::SELECT, XLenVT, Custom`). Run this code through llc (`llc -march=riscv64 -O2`)

  define i64 @foo(i64 %x, i64 %y, i64 %u, i64 %v) {
    %c = icmp sge i64 %x, %y
    %select_ = select i1 %c, i64 %u, i64 %v
    ret i64 %select_
  }

Generic DAG combine will remove the `xor` after legalization:

  Legalized selection DAG: %bb.0 'foo:'
  SelectionDAG has 17 nodes:
    t0: ch,glue = EntryToken
            t2: i64,ch = CopyFromReg t0, Register:i64 %0
            t4: i64,ch = CopyFromReg t0, Register:i64 %1
          t20: i64 = setcc t2, t4, setlt:ch
        t22: i64 = xor t20, Constant:i64<1> <- THIS XOR
        t6: i64,ch = CopyFromReg t0, Register:i64 %2
        t8: i64,ch = CopyFromReg t0, Register:i64 %3
      t11: i64 = select t22, t6, t8
    t13: ch,glue = CopyToReg t0, Register:i64 $x10, t11
    t14: ch = RISCVISD::RET_GLUE t13, Register:i64 $x10, t13:1
  
  
  Optimized legalized selection DAG: %bb.0 'foo:'
  SelectionDAG has 15 nodes:
    t0: ch,glue = EntryToken
          t2: i64,ch = CopyFromReg t0, Register:i64 %0
          t4: i64,ch = CopyFromReg t0, Register:i64 %1
        t20: i64 = setcc t2, t4, setlt:ch
        t8: i64,ch = CopyFromReg t0, Register:i64 %3
        t6: i64,ch = CopyFromReg t0, Register:i64 %2
      t23: i64 = select t20, t8, t6
    t13: ch,glue = CopyToReg t0, Register:i64 $x10, t23
    t14: ch = RISCVISD::RET_GLUE t13, Register:i64 $x10, t13:1

It is done by `DAGCombiner.cpp`, `extractBooleanFlip` which does the right thing depending on  `getBooleanContents`


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155328/new/

https://reviews.llvm.org/D155328



More information about the llvm-commits mailing list