At which point application vs target machine type width splitting happens?

Hello,

I'm trying to understand how fitting source integer type width into
target machine register width happens. My reading on LLVM
codegeneration topics (few megabytes) so far didn't have this topic
mentioned explicitly.

As an example, how

  %1 = add nsw i32 %b, %a

gets compiled into msp430 (16bit CPU) assembly as:

  add.w r13, r15
  addc.w r12, r14

Using -print-before-all -print-after-all, I see that width splitting
happens between last LLVM IR pass and first DAG pass dump. Using
-view-* doesn't give insight either. Nor I was able to find any
adhoc rules related to addc instruction in MSP430InstrInfo.td .

So, it seems to be handled somewhere in target-independent code
generator, can someone give a pointer to the code (and docs on this
specific matter if any, because that's rather important machine-specific
optimization topic IMHO, if you step aside from 32bit world).

Hi Paul,

So, it seems to be handled somewhere in target-independent code
generator, can someone give a pointer to the code (and docs on this
specific matter if any, because that's rather important machine-specific
optimization topic IMHO, if you step aside from 32bit world).

The code you want is in lib/CodeGen/SelectionDAG/LegalizeTypes.cpp. I
think it happens between "-view-legalize-types-dags" and
"-view-dag-combine-lt-dags". Essentially, any type that doesn't have a
valid register class associated to it gets lowered (by expanding in
this case) to operations on types that *do* have legal
register-classes.

Unfortunately it's not got much independent documentation.

Tim.

Hi Paul, this is done by the type legalizer, which lives in the files
   lib/CodeGen/SelectionDAG/Legalize*Types*

Ciao, Duncan.

Hello

I'm trying to understand how fitting source integer type width into
target machine register width happens. My reading on LLVM
codegeneration topics (few megabytes) so far didn't have this topic
mentioned explicitly.

This is done during DAG Legalization phase. The operation is splitted
into two (ADD + ADDC / ADDE). These DAG nodes are later matches during
instruction selection.

Hello,

Hello

> I'm trying to understand how fitting source integer type width into
> target machine register width happens. My reading on LLVM
> codegeneration topics (few megabytes) so far didn't have this topic
> mentioned explicitly.
This is done during DAG Legalization phase. The operation is splitted
into two (ADD + ADDC / ADDE). These DAG nodes are later matches during
instruction selection.

Thanks for all the replies! Taking the hints, here's more datailed
flow for the "%1 = add nsw i32 %b, %a" example if someone later will
google for it:

Source file is LegalizeIntegerTypes.cpp,
DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo).
handles width splitting (which apparently in LLVM slang called
"expanding" which I'm, as a novice, find confusing).

For add/sub, this calls
DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, SDValue &Lo, SDValue
&Hi) which splits value operation into 2 equal by width parts. If
original type is not power-of-2, it appears to be promoted first to
power-of-2 (elsewhere). For longer values, the process of splitting
applies recursively. There doesn't appear to be artificial limits on
operatable width of integer types, for example, msp430 happily adds
i128 values (with awful optimization though, like spilling values having
backing store instead of rematerializing them).

To trace thru "expand" operations, undocumented (?) -debug switch can be
passed to llc.

The codegen document (http://llvm.org/docs/CodeGenerator.html) explains it:

"
There are two main ways of converting values of unsupported scalar
types to values of supported types: converting small types to larger
types (“promoting”), and breaking up large integer types into smaller
ones (“expanding”). For example, a target might require that all f32
values are promoted to f64 and that all i1/i8/i16 values are promoted
to i32. The same target might require that all i64 values be expanded
into pairs of i32 values. These changes can insert sign and zero
extensions as needed to make sure that the final code has the same
behavior as the input.
"

Eli