Closed Quuxplusone closed 14 years ago
Bugzilla Link | PR6429 |
Status | RESOLVED FIXED |
Importance | P normal |
Reported by | Ralf Karrenberg (karrenberg@cs.uni-saarland.de) |
Reported on | 2010-02-26 03:42:41 -0800 |
Last modified on | 2010-03-08 22:18:53 -0800 |
Version | trunk |
Hardware | PC Linux |
CC | clattner@nondot.org, jfonseca@vmware.com, llvm-bugs@lists.llvm.org, llvm@sunfishcode.online |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also |
Looks like a JIT relocation/encoding bug. Within LLI, the instruction looks like this:
UCOMISDrm %XMM0, %reg0, 1, %reg0, <cp#0>, %reg0, %EFLAGS
So it looks like the JIT is patching in a bogus address for the constant pool reference.
Specifically, it looks like it's using a PC-relative encoding, which is wrong here. This decision seems to happen in code substantially modified by r95693. Chris, can you investigate?
P5 priority and normal severity seems an understatement to me.
With the testing I've done here with llvmpipe (a 3D software renderer based on LLVM that's part of Mesa3D project) the trunk's x64_64 JIT is completely useless.
I can't test anything else here with the trunk.
priority and severity don't mean anything in this bugzilla.
I can't reproduce this failure (on darwin/x86-64), all of these modes work fine for me, including the .ll file pasted in the bug.
I'm seeing this GDB disassembly of the generated code:
0x0000000101c2c099: jmpq 0x101c2c0a7
0x0000000101c2c09e: movsd 0x8(%rsp,%rbx,8),%xmm0
0x0000000101c2c0a4: inc %rbx
0x0000000101c2c0a7: ucomisd -0x8f(%rip),%xmm0 # 0x101c2c020
0x0000000101c2c0af: setp %al
0x0000000101c2c0b2: setne %cl
And this is the encoding I'm seeing:
(gdb) x/8bx 0x0000000101c2c0a7
0x101c2c0a7: 0x66 0x0f 0x2e 0x05 0x71 0xff 0xff 0xff
Please include the encoding the you're seeing the x86-64 jit produce.
Dan, if the machineinstr looks like "UCOMISDrm %XMM0, %reg0, 1, %reg0, <cp#0>, %reg0, %EFLAGS
Yes, this is not jit specific at all. You can see this with the static codegen:
$ llc -mtriple=x86_64-linux-gnu t.bc -o -
...
ucomisd .LCPI1_2, %xmm0
setp %al
setne %cl
$ llc t.bc -o -
...
ucomisd LCPI1_2(%rip), %xmm0
setp %al
setne %cl
It looks like the problem is this code in X86InstrInfo.cpp:
switch (LoadMI->getOpcode()) {
case X86::V_SET0:
case X86::V_SETALLONES:
case X86::FsFLD0SD:
case X86::FsFLD0SS: {
// Folding a V_SET0 or V_SETALLONES as a load, to ease register pressure.
// Create a constant-pool entry and operands to load from it.
// x86-32 PIC requires a PIC base register for constant pools.
unsigned PICBase = 0;
if (TM.getRelocationModel() == Reloc::PIC_) {
if (TM.getSubtarget<X86Subtarget>().is64Bit())
PICBase = X86::RIP;
else
// FIXME: PICBase = TM.getInstrInfo()->getGlobalBaseReg(&MF);
// This doesn't work for several reasons.
// 1. GlobalBaseReg may have been spilled.
// 2. It may not be live at MI.
return NULL;
}
The X86TargetLowering::LowerConstantPool function ignores the relocation model,
it uses:
if (Subtarget->isPICStyleRIPRel() &&
(M == CodeModel::Small || M == CodeModel::Kernel))
.. use rip ..
Dan, can you take a look at this? This is all code that you and evan wrote.
(In reply to comment #9)
> Yes, this is not jit specific at all. You can see this with the static
> codegen:
>
> $ llc -mtriple=x86_64-linux-gnu t.bc -o -
> ...
> ucomisd .LCPI1_2, %xmm0
> setp %al
> setne %cl
>
> $ llc t.bc -o -
> ...
> ucomisd LCPI1_2(%rip), %xmm0
> setp %al
> setne %cl
This doesn't indicate a bug (encoding micro-optimization aside). llc is hard-
wired to emit only PIC on Darwin x86-64. On other targets it defaults to
static. In static mode, it's not necessary to use RIP-relative addressing.
That may be, but I have no plans to rewrite the JIT encoder this close to the 2.7 release. If you don't want to fix this for 2.7, I'm fine waiting until 2.8. 2.8 will hopefully have the entire JIT encoder replaced with the existing .o file writer stuff.
I was curious how the JIT copes with code like
x ? 0.1 : 2.3
because this typically codegens as LCPI(,%rax,8), and it's not possible to
encode addresses using the scaled index with RIP. The answer is that the JIT
defaults to the large code model, so the symbol gets emitted in a MOV64ri,
which bypasses this issue.
Given that, the bigger problem here is that that X86InstrInfo.cpp code wasn't
aware of the code model. This is now fixed on trunk in r98042.
It's also the case that the binary code emitter will need more information (a
TargetFlag bit on the MachineOperand?) in order to be able to emit non-PC-
relative encodings, but that's a separate issue.
The new mc encoder should already have the targetflags. If it makes sense to pull into 2.7, please point tanya to the specific revs to pull in.