on a target with only i16 registers, the following code: ulong %foo() { ret ulong 31189350395091 } asserts in legalization: instead of being legalized down to 4xi16, it gets turned into 2xi32 and then trips over an assert (LegalizeDAG.cpp:1458, "Register type must be legal!") - the code there seems to assume that if an integer isn't legal, one "break up" into two smaller regs is sufficient to make it so. This is true for any target with i32 regs since i64 is the biggest we have, but if even i32 isn't legal for a target, further legalization is required.
The code generator is built to allow recursive expansion (expand i64 -> 2xi32 then each i32 -> 2x i16). Unfortunately, without a 16 bit target to test on, I'm sure there are missing cases. In particular, some specific pieces of code (e.g. CopyToReg insertion?) may not be aware that expanding once may not be enough. If you track down the specific cases that don't work, we can get them fixed. What is the stack trace for this failure? -Chris
The stack trace: #3 0x086e9d66 in (anonymous namespace)::SelectionDAGLegalize::LegalizeOp (this=0xbf955350, Op={Val = 0x8a55470, ResNo = 0}) at /home/duraid/strategist/compiler/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1458 #4 0x086e9c84 in (anonymous namespace)::SelectionDAGLegalize::LegalizeOp (this=0xbf955350, Op={Val = 0x8a55500, ResNo = 0}) at /home/duraid/strategist/compiler/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1456 #5 0x086e160e in (anonymous namespace)::SelectionDAGLegalize::LegalizeOp (this=0xbf955350, Op={Val = 0x8a55718, ResNo = 0}) at /home/duraid/strategist/compiler/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:546 #6 0x086f67b7 in (anonymous namespace)::SelectionDAGLegalize::LegalizeOp (this=0xbf955350, Op={Val = 0x8a55230, ResNo = 0}) at /home/duraid/strategist/compiler/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:2854 #7 0x08704dd9 in (anonymous namespace)::SelectionDAGLegalize::HandleOp (this=0xbf955350, Op={Val = 0x8a55230, ResNo = 0}) at /home/duraid/strategist/compiler/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:458 #8 0x087053f2 in (anonymous namespace)::SelectionDAGLegalize::LegalizeDAG (this=0xbf955350) at /home/duraid/strategist/compiler/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:338 #9 0x08705582 in llvm::SelectionDAG::Legalize (this=0xbf9556e4) at /home/duraid/strategist/compiler/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:4980 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ and here's a bit of the DAG at that point: 0x8a552c8: i32 = Constant <3592858835> 0x8a55328: i32 = Constant <7261> 0x8a54fd8: <multiple use> 0x8a54fd8: <multiple use> 0x8a553e8: ch = TokenFactor 0x8a54fd8, 0x8a54fd8 0x8a553e8: <multiple use> 0x8a555e8: i32 = Register r8 0x8a552c8: <multiple use> 0x8a55470: ch,flag = CopyToReg 0x8a553e8, 0x8a555e8, 0x8a552c8
Okay, the problem is that the dag is bogus. Can you find out what is making the i32 copytoreg nodes? SelectionDAGISel should only produce legal width copytoreg's. It's probably the generic lowerret code or your target-specific one. -Chris
OK, I thought it might be my custom RET lowering code at fault, but now I'm not so sure. The problem is, I'm switching on the number of operands the RET has: 1/3/5/7 for ret void/i16/i32/i64. It turns out that it's never even getting to the i64 branch: the ret has 5 operands whether or not it's returning i32 or i64. So I guess the bug is in the generic RET legalize code? Those i32 copytoreg nodes are coming from the 5-operand path in my custom RET lowering code, which is just: MVT::ValueType ArgVT = Op.getOperand(1).getValueType(); assert(MVT::isInteger(ArgVT) && "no FP here buddy"); Copy = DAG.getCopyToReg(Op.getOperand(0), Strategist::r8, Op.getOperand(1), SDOperand()); Copy = DAG.getCopyToReg(Copy, Strategist::r9, Op.getOperand(3), Copy.getValue(1)); return DAG.getNode(StrategistISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
err, I meant 1/3/5/9 of course, not 1/3/5/7.
This should fix the ret i64 case, lemme know if it doesn't. http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20060821/036913.html -Chris