[cfe-dev] Target-specific AST rewriting (clang)

Krzysztof Parzyszek via cfe-dev cfe-dev at lists.llvm.org
Wed Mar 11 09:11:32 PDT 2020


> The AST should reflect that: it should not include a conversion operator that's meaningless at the source level.

Makes sense.  Thanks.

--
Krzysztof Parzyszek  kparzysz at quicinc.com<mailto:kparzysz at quicinc.com>   AI tools development

From: Eli Friedman <efriedma at quicinc.com>
Sent: Monday, March 9, 2020 7:51 PM
To: Krzysztof Parzyszek <kparzysz at quicinc.com>
Cc: cfe-dev at lists.llvm.org
Subject: RE: [EXT] [cfe-dev] Target-specific AST rewriting (clang)

If I'm understanding correctly, in the C AST, the builtin takes an operand of type "vector_bool", which is represented in memory like a "<128 x i8>".  But the corresponding LLVM builtin takes a "<128 x i1>".  So you need to emit a "trunc" or something like that to do the conversion.

>From your description, it sounds like you can declare variables of type vector_bool.  (If not, I'm not sure why you're declaring your intrinsics to have arguments of type vector_bool.)  Given that, the bitcasts seem like a distraction, so I'll pretend they're not there, and the question is just whether we should emit an AST node to represent the conversion from a "memory" vector_bool to a "register" vector_bool.

I think this is not something we should be exposing in the AST.  There is no type conversion at the source level.  The fact that we have to expand the intrinsic call to a sequence of multiple LLVM instructions is a detail of the LLVM backend, not a property of the source language.  The source language is intentionally hiding the fact that a conversion is necessary to invoke the instruction in question. The AST should reflect that: it should not include a conversion operator that's meaningless at the source level.

Note that clang CodeGen does distinguish between "memory" and "register" types for scalar booleans; see CodeGenTypes::ConvertType vs. CodeGenTypes::ConvertTypeForMem .  Maybe that would be more helpful for solving your issue?

-Eli

From: Krzysztof Parzyszek <kparzysz at quicinc.com<mailto:kparzysz at quicinc.com>>
Sent: Monday, March 9, 2020 4:20 PM
To: Eli Friedman <efriedma at quicinc.com<mailto:efriedma at quicinc.com>>
Cc: cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
Subject: Re: [EXT] [cfe-dev] Target-specific AST rewriting (clang)

Assume for brevity that
vector_int = __attribute__((__vector_size__(32 * sizeof(int)))) int
vector_bool = __attribute__((__vector_size__(128 * sizeof(_Bool)))) _Bool

Consider this AST.  It contains bitcasts from vector_bool to vector_int and the other way around.

|     `-ImplicitCastExpr 0x807c212b0 <col:10, col:51> 'HVX_Vector':'vector_int' <BitCast>
|       `-CallExpr 0x807c21220 <col:10, col:51> 'vector_bool'
|         |-ImplicitCastExpr 0x807c21208 <col:10> 'vector_bool (*)(vector_bool, vector_bool)' <BuiltinFnToFnPtr>
|         | `-DeclRefExpr 0x807c21180 <col:10> '<builtin fn type>' Function 0x807c21000 '__builtin_HEXAGON_V6_pred_and_128B' 'vector_bool (vector_bool, vector_bool)'
|         |-ImplicitCastExpr 0x807c21268 <col:45> 'vector_bool' <BitCast>
|         | `-ImplicitCastExpr 0x807c21250 <col:45> 'HVX_Vector':'vector_int' <LValueToRValue>
|         |   `-DeclRefExpr 0x807c211a0 <col:45> 'HVX_Vector':'vector_int' lvalue ParmVar 0x807a43d10 'a0' 'HVX_Vector':'vector_int'
|         `-ImplicitCastExpr 0x807c21298 <col:49> 'vector_bool' <BitCast>
|           `-ImplicitCastExpr 0x807c21280 <col:49> 'HVX_Vector':'vector_int' <LValueToRValue>
|             `-DeclRefExpr 0x807c211c0 <col:49> 'HVX_Vector':'vector_int' lvalue ParmVar 0x807a43d88 'a1' 'HVX_Vector':'vector_int'


  1.  These casts are not no-ops, there are instructions that do it (with corresponding builtins/intrinsics). In the actual hardware, the registers holding vector_int are 1024 bits long, the registers holding vector_bool are 128 bits long.
  2.  The "bool" vectors are not storable directly (i.e. no way to store the 128 bits to memory).  Instead, they have to be "expanded" into vector_int (or contracted from vector_int).  In other words, vector_int is the universal storage format for both types.
Long story short, in C code we want to make these two types look (more or less) the same (i.e. both are 128 bytes), but in LLVM IR they are different (since 32*i32 is not bitcastable to 128*i1).  Now, I want to replace these bitcasts with calls to proper builtins, i.e. transform clang's Expr to another Expr.  Right now we deal with it in CGBuiltin as a part of codegen, but it's not elegant (not composable with other per-builtin handling that may need to happen in CGBuiltin).

-Krzysztof

________________________________
From: Eli Friedman <efriedma at quicinc.com<mailto:efriedma at quicinc.com>>
Sent: Monday, March 9, 2020 4:42 PM
To: Krzysztof Parzyszek <kparzysz at quicinc.com<mailto:kparzysz at quicinc.com>>
Cc: cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org> <cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>>
Subject: RE: [EXT] [cfe-dev] Target-specific AST rewriting (clang)

I'm not sure I follow what you mean.  Do you mean that given, for example "float x; __builtin_foo(-x);", you call "llvm.foo(-x)", and given "double x; __builtin_foo((float)-x)", you call "llvm.bar(-x)"?  I don't think there's any precedent for that, no; normally that's the sort of optimization you'd handle in instcombine.

-Eli

> -----Original Message-----
> From: cfe-dev <cfe-dev-bounces at lists.llvm.org<mailto:cfe-dev-bounces at lists.llvm.org>> On Behalf Of Krzysztof
> Parzyszek via cfe-dev
> Sent: Monday, March 9, 2020 12:57 PM
> To: cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
> Subject: [EXT] [cfe-dev] Target-specific AST rewriting (clang)
>
> Hi,
>
> There are some type casts that should be replaced with intrinsics (this is
> Hexagon-specific). Those only occur in calls to Hexagon builtins, and right now
> this replacement happens as a part of clang's codegen.
> However, this replacement is only triggered by types in the AST and the
> corresponding types in the LLVM IR, and is not dependent on the details
> (semantics) of any particular builtin, so I'd like to make it orthogonal to the
> cgbuiltin code that deals with specific intrinsics. I'd like the replacement to
> transform AST->AST, so the result can be easily composed with any code that
> does AST->LLVM IR.
>
> Is there a precedent for something like this?  I could do this right at the
> beginning of EmitHexagonBuiltinExpr, but I was wondering if there was a better
> way.
>
> --
> Krzysztof Parzyszek  kparzysz at quicinc.com<mailto:kparzysz at quicinc.com>   AI tools development
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org<mailto:cfe-dev at lists.llvm.org>
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200311/8c44eee1/attachment-0001.html>


More information about the cfe-dev mailing list