Address arithmetic result is incorrectly zero-extended (X86)

Hi,

I'm trying to fix bug 12802 [1]. The problem is that the C statement "return ((long)&x) - 600000000;" (where x is a variable defined at file scope) generates the code "movl $x-600000000, %eax" while it should be "movq $x-600000000, %rax". This means that the result is incorrectly zero-extended instead of sign-extended, causing an error with some linkers and incorrect results with some other linkers. It seems like the wrong instruction is selected in X86DAGToDAGISel::SelectMOV64Imm32. I tried to add an extra check that makes the function return false if the offset of the GlobalAddressSDNode is negative, but this causes the instruction selector to not select an instruction at all (it fails with a "Cannot select" error). Any help is appreciated.

-Manuel

[1] http://llvm.org/bugs/show_bug.cgi?id=12802

ping

ping

I tried to
add an extra check that makes the function return false if the offset of the
GlobalAddressSDNode is negative, but this causes the instruction selector to
not select an instruction at all (it fails with a "Cannot select" error).

That's presumably because the function that gets called for the
instruction you *do* want to emit isn't expecting to have to deal with
offset globals and returns false. Your best option is probably to find
it and add the functionality.

It looks like you're most of the way there, having found and modified
the 32-bit function.

Cheers.

Tim.