[LLVMdev] introducing sign extending halfword loads into the LLVM IR

Bjorn De Sutter bjorn.desutter at elis.ugent.be
Mon Jan 21 02:32:40 PST 2013

Hi all,

when compiling code like 

short ptr * = some_address;
int val;

val = *ptr;
if (val>2047)
   val = 2047;
else if (val<-2048)
   val = -2048.
// other things done that require val to be an int ...

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:

- it counts as an instruction in heuristics based on instruction counts (such as SimplifyCFG); as a result some simplifications are not performed;
- 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:

 %0 = load i16* %arrayidx2, align 2, !dbg !502
  %conv = sext i16 %0 to i32, !dbg !502
  %cmp16 = icmp sgt i16 %0, 2047, !dbg !510
  br i1 %cmp16, label %if.end23, label %if.else, !dbg !510

if.else:                                          ; preds = %for.body
  %cmp19 = icmp slt i16 %0, -2048, !dbg !511                                        <--- 16-bit comparison
  %.conv = select i1 %cmp19, i32 -2048, i32 %conv, !dbg !511          <--- 32-bit select
  br label %if.end23, !dbg !511

if.end23:                                         ; preds = %if.else, %for.body
  %val1.0 = phi i32 [ 2047, %for.body ], [ %.conv, %if.else ]
  %conv24 = trunc i32 %val1.0 to i16, !dbg !512
  store i16 %conv24, i16* %arrayidx2, align 2, !dbg !512

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. 

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. 

Any ideas on this? And how big of an effort that might be?


Bjorn De Sutter
Computer Systems Lab
Ghent University

More information about the llvm-dev mailing list