[PATCH] D143796: [SelectionDAG] Negate constant offset before morphing load/store node with pre-dec/post-dec addressing mode.

Huihui Zhang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 14 16:30:52 PST 2023


huihuiz added a comment.

Dumped -debug-only=isel,dagcombine for a few targets (armv7a, aarch64, x86_64, riscv64) to see what's going on. Here is what I found:

1, Not all targets support PRE_DEC addressing mode, we only replace a store with equivalent <pre-dec> store when it's legal to do so.
Take previous AArch64 t.ll for example

  t6: i64 = add nuw nsw t4, Constant:i64<8>
  t15: i64 = shl t6, Constant:i64<2>
  t23: i64 = sub t2, t15
  t13: ch = store<(store (s32) into %ir.t4)> t0, Constant:i32<0>, t23, undef:i64

t13 was replaced with a <pre-dec> store t32

  t27: i64 = shl t4, Constant:i64<2>
  t30: i64 = sub t2, t27
  t32: i64,ch = store<(store (s32) into %ir.t4), <pre-dec>> t0, Constant:i32<0>, t30, Constant:i64<32>

In DAGCombiner::CombineToPreIndexedLoadStore(), before DAG.getIndexedStore() is called, we first check TLI.isIndexedStoreLegal() in getCombineLoadStoreParts().
Then we set AddrMode AM properly.

For targets like x86_64, index store is not legal.

2, For armv7a target, I change the attached t.ll to use 32-bit as gep offset. CodeGen is correct, for two reasons:
i) For ARM target lowering, commute-with-shift is turned off after legalization, but for AArch64 it's returning true when checking isDesiableToCommuteWithShift(). So constant 32 is pulled out for AArch64 target, but not for ARM target.
ii) Negating offset register for ARM target is done in SelectAddrMode2OffsetReg() , the ARM_AM::getAM2Opc() part.
We generate: 
 add     r1, r1, #8
 str     r2, [r3, -r1, lsl #2]! // correct

When Selecting node t26
t6: i32 = add nuw nsw t4, Constant:i32<8>
t14: i32 = shl t6, Constant:i32<2>
t26: i32,ch = store<(store (s32) into %ir.t4), <pre-dec>> t0, Constant:i32<0>, t2, t14

we got 
Morphed node: t26: i32,ch = STRr_preidx<Mem:(store (s32) into %ir.t4)> Constant:i32<0>, t2, t6, TargetConstant:i32<20482>, TargetConstant:i32<14>, Register:i32 $noreg, t0

TargetConstant:i32<20482> , bit 13 is set to 1 to indicate doing subtraction.

3, I don't seem to find similar handling for AArch64 target. If I am looking at the wrong direction, please point me out?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D143796



More information about the llvm-commits mailing list