[PATCH] D59339: [GISel][Legalizer][WIP][RFC] Retry legalization for failing instrs when artifacts are around

Petar Avramovic via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 15 07:12:23 PDT 2019


Petar.Avramovic added a comment.

I did not consider the case where sequence of instruction is legal, but individual instructions are not.
Condition when we throw an error might become 
`if (ArtifactList.empty() && TryLaterArtifactList.empty()) `
but other then that, there is no conflicts with artifact combining so it should not be a problem.

here is a small example:
i64 is held as two i32s.

  define i64 @f(i32 %x) {
  entry:
    %conv = zext i32 %x to i64
    ret i64 %conv
  }

IRTranslator gives:

  %0:_(s32) = COPY $a0
  %1:_(s64) = G_ZEXT %0(s32)
  %2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1(s64)
  $v0 = COPY %2(s32)
  $v1 = COPY %3(s32)
  RetRA implicit $v0, implicit $v1

In Legalizer, ArtifactList contains:

  %1:_(s64) = G_ZEXT %0:_(s32)
  %2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1:_(s64)

and we go bottom up.

Here 
Artifact  `%2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1:_(s64) `
Has nothing to combine with at the moment, but it has artifact use (zext) and goes to TryLaterArtifactList
Artifact `%1:_(s64) = G_ZEXT %0:_(s32)` had nothing to combine with, and is moved to InstList

Instruction `%1:_(s64) = G_ZEXT %0:_(s32)` gets narrowScalar-ed:

  %0:_(s32) = COPY $a0
  %1:_(s64) = G_ZEXT %0:_(s32)

Into:

  %4:_(s32) = G_CONSTANT i32 0
  %1:_(s64) = G_MERGE_VALUES %0:_(s32), %4:_(s32)

ArtifactList contains:

  %1:_(s64) = G_MERGE_VALUES %0:_(s32), %4:_(s32)

G_MERGE_VALUES gets turned into instruction and legalized (it is legal).

now we move TryLaterArtifactList to ArtifactList
ArtifactList contains:
` %2:_(s32), %3:_(s32) = G_UNMERGE_VALUES %1:_(s64)`
it gets combined with
 `%1:_(s64) = G_MERGE_VALUES %0:_(s32), %4:_(s32)`

we get:

  %0:_(s32) = COPY $a0
  %4:_(s32) = G_CONSTANT i32 0
  $v0 = COPY %0(s32)
  $v1 = COPY %4(s32)
  RetRA implicit $v0, implicit $v1

>> We could try to implement some constant elimination once they are properly legalized.
> 
> Don't we have that for free already? If something is not dead we keep it, otherwise we remove it. What am I missing?

Constant combining is probably a better term. 
For example when we want to store i1 true/false, target decides if it wants it zero/sign extended to size that it specifies. Here we can combine away explicit sign/zero extend + G_CONSTANT and create appropriate constant. 
I am not completely sure how to treat constants, this is just an idea.

Btw, we might want to perform combine of (-O0 in clang frontend)

  %0:_(s32) = COPY $a0
  %1:_(s32) = G_CONSTANT i32 2
  %2:_(s32) = G_CONSTANT i32 3
  %3:_(s32) = G_ADD %0, %1
  %4:_(s32) = G_ADD %3, %2

into

  %0:_(s32) = COPY $a0
  %5:_(s32) = G_CONSTANT i32 5
  %6:_(s32) = G_ADD %0, %5

There are passes in middle-end that perform this kind of optimization so we might want to skip this.
On the other hand SDAG can perform this kind of optimization.


Repository:
  rL LLVM

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

https://reviews.llvm.org/D59339





More information about the llvm-commits mailing list