<div dir="ltr"><div>Instruction selection happens on a different IR: SelectionDAG.  In this IR, there are sign-extending loads that the IR converter will use, and are used for example to load 8/16-bit values into 32-bit registers (with sign or zero extension).  Any optimizations performed during codegen will be in this representation, or even MachineInstr form, which is post-isel and any sign-extension information will already be folded into the machine instruction.<br>
<br></div><div>The problem with doing machine-level analysis on LLVM IR is that there is no guarantee that LLVM IR will be an accurate representation of what the final code will look like instruction-wise.  LLVM IR can express many operations that are not legal for a given target and so must be expanded into more than one operation.  Or the target may support combination instructions that allow multiple LLVM IR instructions to be folded into one machine instruction.  All of these are handled during SelectionDAG generation and instruction selection, and complicate LLVM IR-level analysis of machine-level characteristics.  For the load example you give, on any architecture that supports sign-extending loads, the load and sext will be combined into a single instruction (a "load ... <sext from i16>" in SelectionDAG).<br>
<br></div><div>We could definitely try to capture more of the optimization cases you mention, but I'm not sure adding a sign-extending load to the IR would buy us much.  In what cases would a front-end choose to generate a 16-bit load sign-extended to i32 instead of an i16 load?  This seems like it would only generate ambiguity.  Generally, we don't extend the core IR if something is already expressible.  For what it's worth, the max detection could fairly easily be done in a back-end isel pattern.<br>
</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Jan 21, 2013 at 5:32 AM, Bjorn De Sutter <span dir="ltr"><<a href="mailto:bjorn.desutter@elis.ugent.be" target="_blank">bjorn.desutter@elis.ugent.be</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all,<br>
<br>
when compiling code like<br>
<br>
short ptr * = some_address;<br>
int val;<br>
<br>
val = *ptr;<br>
if (val>2047)<br>
   val = 2047;<br>
else if (val<-2048)<br>
   val = -2048.<br>
// other things done that require val to be an int ...<br>
<br>
The load operation is represented by a load and a sign extension operation in the LLVM IR. On most target architectures, there exist signed halfword load instructions, so the load and sign extension are effectively translated into a single instruction during instruction selection. Nonetheless, this sign extension operation in the IR prohibits a lot of optimizations:<br>

<br>
- it counts as an instruction in heuristics based on instruction counts (such as SimplifyCFG); as a result some simplifications are not performed;<br>
- the sign extension operation gets combined with other operations. In the example, the sign extension gets combined with the 32-bit comparison implementing the val>-2048, resulting in a 16-bit comparison on the non-extended value; the result is a comparison operation on 16-bit operands, followed by a select operation on 32-bit operands:<br>

<br>
 %0 = load i16* %arrayidx2, align 2, !dbg !502<br>
  %conv = sext i16 %0 to i32, !dbg !502<br>
  %cmp16 = icmp sgt i16 %0, 2047, !dbg !510<br>
  br i1 %cmp16, label %if.end23, label %if.else, !dbg !510<br>
<br>
if.else:                                          ; preds = %for.body<br>
  %cmp19 = icmp slt i16 %0, -2048, !dbg !511                                        <--- 16-bit comparison<br>
  %.conv = select i1 %cmp19, i32 -2048, i32 %conv, !dbg !511          <--- 32-bit select<br>
  br label %if.end23, !dbg !511<br>
<br>
if.end23:                                         ; preds = %if.else, %for.body<br>
  %val1.0 = phi i32 [ 2047, %for.body ], [ %.conv, %if.else ]<br>
  %conv24 = trunc i32 %val1.0 to i16, !dbg !512<br>
  store i16 %conv24, i16* %arrayidx2, align 2, !dbg !512<br>
<br>
The problem with this is that during instruction selection, the pair of comparison and select is no longer recognized as max operation because the operands of the two operations are not the same.<br>
<br>
It seems to me that these and other limitations on the applied optimizations could easily be avoided by introducing a sign-extending halfword load operation into the IR.<br>
<br>
Any ideas on this? And how big of an effort that might be?<br>
<br>
Thanks,<br>
<br>
Bjorn De Sutter<br>
Computer Systems Lab<br>
Ghent University<br>
<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote></div><br><br clear="all"><br>-- <br><br><div>Thanks,</div><div><br></div><div>Justin Holewinski</div>
</div>