[llvm-dev] Dealing with boolean values in GlobalISel

Arsenault, Matthew via llvm-dev llvm-dev at lists.llvm.org
Fri Sep 27 12:47:21 PDT 2019


Hi,

I’ve been thinking about what the strategy to use for boolean values in GlobalISel. There are a few semantic and mechanical issues I’ve encountered.

For background, on AMDGPU, there are two kinds of bool/s1 values. Contextually, a real boolean value will either be a 1-bit scalar condition (in a non-allocatable physical condition register, which will need to be copied to an allocatable class 32-bit vreg during selection), or a vector condition where the s1 will really be a lane mask of results in a 32 or 64-bit SGPR. This will be known during RegBankSelect. To represent this, I’m using two different pseudo register banks used for operands that really function as booleans (select/br conditions, compare results, and a few intrinsics). These two banks physically alias the SGPR bank, but contextually function differently than an s1 value from a non-boolean source (e.g. a G_LOAD of s1 or G_TRUNC to s1). G_SELECT (s1 G_LOAD) would be illegal for example without inserting some kind of compare between the load and select boolean use.

The primary problem I’m currently aiming to solve is losing this contextual pseudo-register bank information once an instruction is selected, as a virtual register can only have either a register bank or register class. Just considering the register class with a type of s1 is ambiguous for whether it was a scalar or vector condition. Once the use instruction is selected, the operands are constrained discarding the register bank before the def instruction is selected. For the generated selectors, GIM_CheckRegBankForClass will then reject the def instruction.

It’s most natural to consider the destination register class in the selector, but I can imagine a variety of burdensome workarounds for this problem. Currently the manual selection of G_SELECT inserts an extra copy to an extra virtual register when selecting the boolean as a workaround.

The other question solving this depends on is what should be responsible for ensuring booleaness of operands as necessary. With the pseudoregister bank strategy, a COPY will be inserted which can be implemented as the necessary compare. AArch64 currently uses a different strategy. Compares have an s32 result type, G_SELECT uses an s1 input type, and G_BRCOND allows s1, s8, s16 or s32. The selector inserts an ANDSWri on the condition while handling G_BRCOND and G_SELECT conditions. I would have to insert an extract of the low bit, and a compare which seems unnatural to me in the selector for the use. I also think this would be an easily forgotten detail requiring manual selection code for all boolean sourced intrinsics.

For example, in this function:
define i32 @foo(i32 %a, i32 %b, i32 %c) {
  %cc = trunc i32 %a to i1
  %r = select i1 %cc, i32 %b, i32 %c
  ret i32 %r
}

SelectionDAG legalizes this to:
  t0: ch = EntryToken
        t2: i32,ch = CopyFromReg t0, Register:i32 %0
      t14: i32 = and t2, Constant:i32<1>
      t4: i32,ch = CopyFromReg t0, Register:i32 %1
      t6: i32,ch = CopyFromReg t0, Register:i32 %2
    t8: i32 = select t14, t4, t6
  t10: ch,glue = CopyToReg t0, Register:i32 $w0, t8
  t11: ch = AArch64ISD::RET_FLAG t10, Register:i32 $w0, t10:1

Such that the selector doesn’t need to worry about the edge case of a non-boolean s1 value.

Can we make truncates to s1 illegal? The documentation currently states it must be legal for all result types for a legal source type, and is a no-op bit operation to make types match only. It would simplify issues if I could legalize such that the selector never needs to worry about the possibility of a non-bool s1 value. I could get rid of the SCC bank, as it needs to be copied to a normal vreg anynway. I would still need to do something to disambiguate scalar and vector bools.

-Matt

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190927/a367902e/attachment.html>


More information about the llvm-dev mailing list