[PATCH] D95564: [GlobalISel] Add G_ASSERT_ZEXT

Jessica Paquette via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 27 14:30:50 PST 2021


paquette created this revision.
paquette added reviewers: aemerson, arsenm.
Herald added subscribers: dexonsmith, hiraditya, kristof.beyls, rovka.
paquette requested review of this revision.
Herald added a subscriber: wdng.
Herald added a project: LLVM.

This adds a generic opcode which communicates that a type has already been zero-extended from a narrower type.

This is intended to be similar to AssertZext in SelectionDAG.

For example,

  %x_was_extended:_(s64) = G_ASSERT_ZEXT %x, 16

Signifies that the top 48 bits of %x are known to be 0.

This is useful in cases like this:

  define i1 @zeroext_param(i8 zeroext %x) {
      %cmp = icmp ult i8 %x, -20
      ret i1 %cmp
  }

In AArch64, `%x` must use a 32-bit register, which is then truncated to a 8-bit value.

If we know that `%x` is already zero-ed out in the relevant high bits, we can avoid the truncate.

Currently, in GISel, this looks like this:

  _zeroext_param:
      and w8, w0, #0xff ; We don't actually need this!
      cmp w8, #236
      cset w0, lo
      ret

While SDAG does not produce the truncation, since it knows that it's unnecessary:

  _zeroext_param:
      cmp w0, #236
      cset w0, lo
      ret

This patch

- Adds G_ASSERT_ZEXT
- Adds MIRBuilder support for it
- Adds MachineVerifier support for it
- Documents it

It also puts G_ASSERT_ZEXT into its own class of "hint instruction." (There should be a G_ASSERT_SEXT in the future, maybe a G_ASSERT_ALIGN as well.)

The reason for doing this rather than making it a pseudo like, say, COPY, is that these *are* pre-ISel generic opcodes. The only difference is

1. They should be ignored by the legalizer
2. They shouldn't impact register bank selection
3. They should select to nothing

To make it easier to skip over hint instructions, this adds `isSelectablePreISelGenericOpcode` to represent non-hint generic instructions, and `isPreISelGenericOptimizationHint` to represent hint generic instructions.

Currently, these are restricted so that they don't appear in regbankselect. This is just to avoid interference with register bank selection. (e.g. AArch64 has some tricky cases with walking through uses/defs for G_PHI, G_SELECT, etc.) I'm not hugely attached to this restriction, and mostly added it for the sake of caution. If anyone can think of any reasons to let these live beyond regbankselect, I'm happy to remove it.


https://reviews.llvm.org/D95564

Files:
  llvm/docs/GlobalISel/GenericOpcode.rst
  llvm/include/llvm/CodeGen/GlobalISel/MachineIRBuilder.h
  llvm/include/llvm/CodeGen/TargetOpcodes.h
  llvm/include/llvm/Support/TargetOpcodes.def
  llvm/include/llvm/Target/GenericOpcodes.td
  llvm/lib/CodeGen/GlobalISel/Legalizer.cpp
  llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
  llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
  llvm/lib/CodeGen/MachineVerifier.cpp
  llvm/test/CodeGen/AArch64/GlobalISel/legalize-ignore-hint.mir
  llvm/test/MachineVerifier/test_g_assert_ext.mir
  llvm/test/MachineVerifier/test_hint_properties.mir

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95564.319677.patch
Type: text/x-patch
Size: 13086 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210127/59df9fdb/attachment.bin>


More information about the llvm-commits mailing list