[llvm] [RISCV][WIP] Fold (sh3add Z, (add X, (slli Y, 6))) -> (sh3add (sh3add Y, Z), X). (PR #85734)

Mikhail Gudim via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 18 23:17:02 PDT 2024


mgudim wrote:

I tried to run isel on this IR:

```
define dso_local signext i64 @foo(i64 noundef signext %x, i64 noundef signext %y, i64 noundef signext %z) local_unnamed_addr #0 {
entry:
  %shl = shl i64 %z, 3
  %shl1 = shl i64 %y, 6
  %add = add nsw i64 %shl1, %shl
  %add2 = add nsw i64 %add, %x
  ret i64 %add2
}
```

which is `(z << 3 + y << 6) + x` and dag combine simplified it to `(y << 3 + z) << 3 + x`:

```
=== foo

Initial selection DAG: %bb.0 'foo:entry'
SelectionDAG has 16 nodes:
  t0: ch,glue = EntryToken
          t4: i64,ch = CopyFromReg t0, Register:i64 %1
        t10: i64 = shl t4, Constant:i64<6>
          t6: i64,ch = CopyFromReg t0, Register:i64 %2
        t8: i64 = shl t6, Constant:i64<3>
      t11: i64 = add nsw t10, t8
      t2: i64,ch = CopyFromReg t0, Register:i64 %0
    t12: i64 = add nsw t11, t2
  t14: ch,glue = CopyToReg t0, Register:i64 $x10, t12
  t15: ch = RISCVISD::RET_GLUE t14, Register:i64 $x10, t14:1



Optimized lowered selection DAG: %bb.0 'foo:entry'
SelectionDAG has 15 nodes:
  t0: ch,glue = EntryToken
            t4: i64,ch = CopyFromReg t0, Register:i64 %1
          t16: i64 = shl t4, Constant:i64<3>
          t6: i64,ch = CopyFromReg t0, Register:i64 %2
        t17: i64 = add t16, t6
      t18: i64 = shl t17, Constant:i64<3>
      t2: i64,ch = CopyFromReg t0, Register:i64 %0
    t12: i64 = add nsw t18, t2
  t14: ch,glue = CopyToReg t0, Register:i64 $x10, t12
  t15: ch = RISCVISD::RET_GLUE t14, Register:i64 $x10, t14:1

```

so I think what's missing is the ability to reassociate the expression. I ran a simpler example to see if dag combine can do a simple reassosiation. From this IR:

```
; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) uwtable
define dso_local signext i64 @foo(i64 noundef signext %x, i64 noundef signext %y, i64 noundef signext %z) local_unnamed_addr #0 {
entry:
  %add1 = add i64 %z, 3
  %add2 = add i64 %y, 6
  %add3 = add nsw i64 %add1, %add2
  ret i64 %add3
}
```

dag combine could reassociate:

```
=== foo

Initial selection DAG: %bb.0 'foo:entry'
SelectionDAG has 15 nodes:
  t0: ch,glue = EntryToken
  t2: i64,ch = CopyFromReg t0, Register:i64 %0
        t6: i64,ch = CopyFromReg t0, Register:i64 %2
      t8: i64 = add t6, Constant:i64<3>
        t4: i64,ch = CopyFromReg t0, Register:i64 %1
      t10: i64 = add t4, Constant:i64<6>
    t11: i64 = add nsw t8, t10
  t13: ch,glue = CopyToReg t0, Register:i64 $x10, t11
  t14: ch = RISCVISD::RET_GLUE t13, Register:i64 $x10, t13:1



Optimized lowered selection DAG: %bb.0 'foo:entry'
SelectionDAG has 11 nodes:
  t0: ch,glue = EntryToken
        t4: i64,ch = CopyFromReg t0, Register:i64 %1
        t6: i64,ch = CopyFromReg t0, Register:i64 %2
      t17: i64 = add t4, t6
    t20: i64 = add t17, Constant:i64<9>
  t13: ch,glue = CopyToReg t0, Register:i64 $x10, t20
  t14: ch = RISCVISD::RET_GLUE t13, Register:i64 $x10, t13:1

```

So it looks like we can do this by generalizing existing dag combines?

https://github.com/llvm/llvm-project/pull/85734


More information about the llvm-commits mailing list