diff mbox

LLVM and PSEUDO_REG/PSEUDO_PHI

Message ID alpine.DEB.2.00.1108292242110.24020@localhost6.localdomain6 (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Pekka Enberg Aug. 29, 2011, 7:45 p.m. UTC
[ Adding sparse-linux to CC. ]

On Sat, 27 Aug 2011, Linus Torvalds wrote:
> On Sat, Aug 27, 2011 at 2:19 AM, Pekka Enberg <penberg@kernel.org> wrote:
>>
>> Looking at this:
>>
>> sete:
>> .L0x7f188cf71c90:
>>        <entry-point>
>>        seteq.32    %r83 <- %arg1, %arg2
>>        cast.32     %r84 <- (8) %r83
>>        ret.32      %r84
>>
>> Why do we have "seteq.32" there but then we have a "cast.32" from %r83 which
>> is 8 bits? Isn't it linearize.c that's confused here?
>
> No, the code is correct, you misunderstand what "seteq" does.
>
> The 32 in "seteq.32" is the OPERAND WIDTH. It takes two 32-bit values
> and checks that they are equal.
>
> The OUTPUT WIDTH is "boolean". Which you changed to 8 bits (to match
> x86 semantics). So when you return an "int", you do indeed need to
> cast from 8 bits to 32 bits.
>
> There are a few ops that have different operand width from output
> width. The cast operation itself is the obvious case, and it shows its
> operand/output widths explicitly. But "setcc" is another - since the
> output is always just a boolean.

So you were obviously correct. I checked the LLVM bitcode and I was simply 
using the wrong type of cast. With this small change:


the generated code now looks sane:

0000000000000000 <sete>:
    0:	39 f7                	cmp    %esi,%edi
    2:	0f 94 c0             	sete   %al
    5:	0f b6 c0             	movzbl %al,%eax
    8:	c3                   	retq
    9:	eb 05                	jmp    10 <setne>

However, i'm not 100% sure that's sufficient. Is OP_CAST always 
zero-extend or do we need to check for something specific here?

 			Pekka
diff mbox

Patch

diff --git a/sparse-llvm.c b/sparse-llvm.c
index f89f7a7..a9bf679 100644
--- a/sparse-llvm.c
+++ b/sparse-llvm.c
@@ -607,7 +607,7 @@  static void output_op_cast(struct function *fn, struct instruction *insn)
  	if (symbol_is_fp_type(insn->type))
  		target = LLVMBuildFPCast(fn->builder, src, symbol_type(insn->type), target_name);
  	else
-		target = LLVMBuildIntCast(fn->builder, src, symbol_type(insn->type), target_name);
+		target = LLVMBuildZExt(fn->builder, src, symbol_type(insn->type), target_name);

  	insn->target->priv = target;
  }