[LLVMdev] Predicate registers/condition codes question

Sebastian Pop spop at codeaurora.org
Fri Jun 1 09:19:15 PDT 2012


Salut Ivan,

On Fri, Jun 1, 2012 at 7:22 AM, Ivan Llopard <ivanllopard at gmail.com> wrote:
> Hi Sebastian,
>
> Le 25/05/2012 18:54, Sebastian Pop a écrit :
>> On Thu, May 24, 2012 at 5:40 PM, Sebastian Pop<spop at codeaurora.org>  wrote:
>>> On Thu, May 24, 2012 at 5:06 PM, Hal Finkel<hfinkel at anl.gov>  wrote:
>>>> Sebastian,
>>>>
>>>> First, it might be useful to look at what is done in the PowerPC
>>>> backend. PPC also has condition registers that are larger than the
>>>> 1-bit conditional results, and it defines 1-bit subregisters in
>>>> addition to the larger condition registers. The spill-restore code ends
>>>> up being more complicated, but that, perhaps, is a separate issue. [To
>>>> be clear, I am not advocating for (or against) this solution even if it
>>>> would work for you].
>>> Ok, thanks for the pointer, I'll go read in the PPC bits.
>> I see that PPC has its condition registers CRRC as i32, and that PPC
>> also has general purpose i32 registers GPRC, so the situation is slightly
>> different than on Hexagon, where there are no general purpose registers
>> of the same size as the predicate registers: i8.
>>
>> So on PPC it is "safe" to promote from i1 to i32 and to "allow confusion"
>> between the promoted i32 and the existing operations that were using i32:
>> as we can always select between a CR and a GPR following the op type.
>>
>> On Hexagon, if type legalization promotes i1 into i8, that would create
>> this confusion between the i8 ops existing before legalization and the
>> newly promoted ones.  Then as Ivan was suggesting, we will have to
>> provide custom expansion to promote the "illegal" ops on i8 on almost
>> all the operations, except logical ops.
>
> I think there is also another (and cleaner) workaround, a kind of
> operation-based type promotion of __illegal__ types.
> This can be done by simply setting the operation with illegal type
> result to have a custom expander, for example:
>
> setOperationAction(ISD::AND, MVT::i1, Custom)
>

I was exploring something similar using exactly this function.

> See LowerOperationWrapper() & ReplaceNodeResults() hooks in
> TargetLowering. If you make this work only on logical ops, the rest will
> get automatically promoted by setting the promotion of i1 to be i32 by

I think I was not clear enough in my past emails, so let me try again:

As I am specifying that predicate registers are i8, LLVM considers i8
to be a legal type.  i1 is then automatically promoted to the next
larger legal type, that is i8: this is the correct behavior.

The problem is that the existing integer arithmetic operations on i8
are not legal to be executed on the predicate registers (i.e., clang
would generate an i8 expression for the addition of two char
variables.)  Hexagon cannot do integer arithmetic operations using the
predicate registers.  The addition of two char variables has to be
promoted to the next available integer arithmetic register: that is
i32.  Because LLVM automatically legalizes i8 types, it considers all
operations to be legal on i8 (i.e., both integer and boolean arithmetic.)

So the solution that I was investigating looks like this:

    for (unsigned int i = 0; i < ISD::BUILTIN_OP_END; ++i) {
      switch (i) {
      // By default all operations on i8 have to be promoted to i32.
      default:
        setOperationAction(i, MVT::i8, Custom);
        break;

      // Only the following operations are legal on i8 predicates.
      case ISD::AND:
      case ISD::OR:
      case ISD::XOR:
      case ISD::SETCC:
      case ISD::SIGN_EXTEND:
       break;
      }
    }

and promote all i8 to i32 in HexagonTargetLowering::LowerOperation

> default. The latter will require a little hack though...
> I hope this helps.

Thanks again for your ideas and guidance: very much appreciated.

Sebastian
--
Qualcomm Innovation Center, Inc is a member of Code Aurora Forum




More information about the llvm-dev mailing list