instruction selector failure

hi,

i found a problem in LLVM regarding the matching of 'Constant' nodes in
the instruction selector. the testcase is for x86, but similar testcases
for the other architectures (e.g. ppc) should be easy to create.

i'm using the llvm-gcc 2.0 prerelease binary package.

here is the testcase:
int foo(int bar) {
  asm("movl %1, %0" : "=r"(bar) : "i"(5));
  return 11;
}

the problem here is, that the constant node '11' is shared by a
CopyToReg node (for the return) and the INLINEASM node. the INLINEASM
node uses the constant as a flag indicating that an immediate operand (5
in this case) follows.

the instruction selector rewrites the constant node into a MOV32ri.
which causes the scheduler to crash with the following error message:

[brandner:~/tmp:720]
/raid0/brandner/llvm-2.0/llvm-gcc4-2.0-x86-linux-RHEL4/bin/llvm-gcc -c
test.c -O1
cc1:
/mounts/zion/disks/0/localhome/tbrethou/llvm/include/llvm/Support/Casting.h:199:
typename llvm::cast_retty<To, From>::ret_type llvm::cast(const Y&) [with
X = llvm::ConstantSDNode, Y = llvm::SDOperand]: Assertion `isa<X>(Val)
&& "cast<Ty>() argument of incompatible type!"' failed.
test.c:4: internal compiler error: Aborted
Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://llvm.org/bugs> for instructions.

a backtrace in cc1 shows:
(gdb) bt
#0 0xf7da55df in raise () from /lib32/libc.so.6
#1 0xf7da6b13 in abort () from /lib32/libc.so.6
#2 0xf7d9edac in __assert_fail () from /lib32/libc.so.6
#3 0x085c63f4 in llvm::ScheduleDAG::EmitNode ()
(gdb)

i would like to fix this bug, but it is hard to tell the real source of
the problem:
1.) it could be an error during the legalization. sharing the constant
node could be prevented. this would not cause the instruction selector
to rewrite the constant node.
2.) the error is in the instruction selector, which should duplicate the
constant node.
3.) the instruction selector should not select flags of INLINE and CALL
nodes. instead it should just copy the original nodes.

i would prefer solution 3, any suggestions on this?

cheers,
florian

Yes. this is fixed in mainline, with this series of patches:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049609.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049608.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049606.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049603.html

Given the invasiveness of these patches, and the lack of significant testing since the have gone into mainline, I'd recommend against merging them into 2.0.

If this blocks a significant piece of software from building with LLVM 2.0 though, we may reconsider. What does it break?

-Chris

Chris Lattner wrote:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049609.html

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049608.html

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049606.html

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070514/049603.html

thank you for the hint.

If this blocks a significant piece of software from building with LLVM
2.0 though, we may reconsider. What does it break?

the problem is caused by an internal application. it is not publicly
available, so it should not be an issue for the release.

thank you,
florian

Ok, as it turns out, we ended up deciding to merge it into the release, so llvm 2.0 should have the fix.

-Chris