Lee Hammerton
2013-Mar-18 18:34 UTC
[LLVMdev] Hit a snag while attempting to write a backend - any advice?
Hi, I've been experimenting with writing a backend for LLVM (3.2) (having already written a frontend http://savourysnax.github.com/EDL), everything was going reasonably ok ( calls/returns, epilogue, prologue, etc are all working), up until I tried to place support for conditional branches. Given this simple program : int test(int c,int d) { if (c) { return d; } else { return c; } } with optimisations disabled (opts enabled it generates a select and this works fine) - I get the error at the bottom of the post. It seems to state, the problem is in the usage of - %R0 in : JMP <BB#3>, %R0<imp-use> what is confusing me, is the implied R0 on the jump, it only appears at Post SSA, and i`m not sure where to look to discern what i've done to cause it. I've tested the same code with the x86 backend and it never seems to do this implied usage. I realise I've not left you a lot to go on, but I`m really just looking for likely areas to go poke around in. The backend was started by copying the MSP430 backend then commenting out large swathes of things (I may have left something in that causes the below error). I'm not using (or shouldn't be) any custom lowering, all instructions map to DAG concepts (with the exception of select_cc and br_cc which are set to expand). Any pointers would be much appreciated - I can post code etc, if required. Thanks, Lee # Machine code for function test: Post SSA Frame Objects: fi#0: size=4, align=4, at location [SP] fi#1: size=4, align=4, at location [SP] fi#2: size=4, align=4, at location [SP] Function Live Ins: %R0 in %vreg0, %R1 in %vreg1 Function Live Outs: %R0 BB#0: derived from LLVM BB %entry Live Ins: %R0 %R1 %vreg1<def> = COPY %R1<kill>; GR32:%vreg1 %vreg0<def> = COPY %R0; GR32:%vreg0 MOV32mr <fi#1>, 0, %vreg0<kill>; mem:ST4[%c.addr] GR32:%vreg0 MOV32mr <fi#2>, 0, %vreg1<kill>; mem:ST4[%d.addr] GR32:%vreg1 %vreg2<def> = MOV32rm <fi#1>, 0; mem:LD4[%c.addr] GR32:%vreg2 %vreg3<def> = CMPfri %vreg2<kill>, 0; SR1:%vreg3 GR32:%vreg2 JCC %vreg3<kill>, <BB#2>; SR1:%vreg3 JMP <BB#1>, %R0<imp-use> Successors according to CFG: BB#1(20) BB#2(12) BB#1: derived from LLVM BB %if.then Predecessors according to CFG: BB#0 %vreg5<def> = MOV32rm <fi#2>, 0; mem:LD4[%d.addr] GR32:%vreg5 MOV32mr <fi#0>, 0, %vreg5<kill>; mem:ST4[%retval] GR32:%vreg5 JMP <BB#3>, %R0<imp-use> Successors according to CFG: BB#3 BB#2: derived from LLVM BB %if.else Predecessors according to CFG: BB#0 %vreg4<def> = MOV32rm <fi#1>, 0; mem:LD4[%c.addr] GR32:%vreg4 MOV32mr <fi#0>, 0, %vreg4<kill>; mem:ST4[%retval] GR32:%vreg4 Successors according to CFG: BB#3 BB#3: derived from LLVM BB %return Predecessors according to CFG: BB#2 BB#1 %vreg6<def> = MOV32rm <fi#0>, 0; mem:LD4[%retval] GR32:%vreg6 %R0<def> = COPY %vreg6<kill>; GR32:%vreg6 RET %R0<imp-use,kill> # End machine code for function test. *** Bad machine code: Using an undefined physical register *** - function: test - basic block: BB#1 if.then (0xea46f84) - instruction: JMP <BB#3>, %R0<imp-use> - operand 1: %R0<imp-use> LLVM ERROR: Found 1 machine code errors. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130318/c346c7a8/attachment.html>
Lee Hammerton
2013-Mar-21 05:28 UTC
[LLVMdev] Hit a snag while attempting to write a backend - any advice?
On Mon, Mar 18, 2013 at 6:34 PM, Lee Hammerton <savoury.snax at googlemail.com>wrote:> Hi, > > I've been experimenting with writing a backend for LLVM (3.2) (having > already written a frontend http://savourysnax.github.com/EDL), everything > was going reasonably ok ( calls/returns, epilogue, prologue, etc are all > working), up until I tried to place support for conditional branches. > > Given this simple program : > > int test(int c,int d) > { > if (c) > { > return d; > } > else > { > return c; > } > } > > with optimisations disabled (opts enabled it generates a select and this > works fine) - I get the error at the bottom of the post. > > > >I've attached the .ll file and output from runnnig llc -debug in the hopes that someone can see the problem. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130321/92380e3b/attachment.html> -------------- next part -------------- A non-text attachment was scrubbed... Name: err Type: application/octet-stream Size: 47972 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130321/92380e3b/attachment.obj> -------------- next part -------------- A non-text attachment was scrubbed... Name: 08-simple.c.ll Type: application/octet-stream Size: 882 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130321/92380e3b/attachment-0001.obj>
Tim Northover
2013-Mar-21 11:55 UTC
[LLVMdev] Hit a snag while attempting to write a backend - any advice?
Hi Lee,> JMP <BB#1>, %R0<imp-use>To me it looks like your JMP instruction (in XXXInstrInfo.td) somehow says it uses R0 (the normal link register on your target, since RET also uses it?). I'd have to see the code to be sure, but since it's implicit I'd first look for a "let Uses = [R0] in" which applies to the JMP instruction, but perhaps should only apply to RET? A misplaced closing brace '}' possibly? If you could post the exact snippet around the definition of JMP we might be able to come up with more. Cheers. Tim.
Tim Northover
2013-Mar-21 13:09 UTC
[LLVMdev] Hit a snag while attempting to write a backend - any advice?
Hi Lee,> let isReturn = 1, isTerminator = 1, isBarrier = 1 in > { > def RET : BitscuitInst<(outs),(ins),"JMP\tR6",[(Bitscuit_return)]>; > > def JMP : BitscuitInst<(outs), (ins jmptarget:$dst),"JMP\t$dst",[(br > bb:$dst)]>; > }Ah! It looks like the isReturn is to blame then. LLVM is presumably going through adding an implicit use of any register that will hold a return value to instructions that will actually return. This would prevent it from removing instructions that actually define R0 as dead code (it's "used" by the RET and should certainly be defined by the time the function does return). Since you've marked *any* JMP as a return, they all seem to get the extra R0, even if the instructions that actually define it hasn't been executed yet. I'd make isReturn only apply to the RET (and probably add an "isBranch" to all of them for good measure). Tim.
Tim Northover
2013-Mar-21 13:54 UTC
[LLVMdev] Hit a snag while attempting to write a backend - any advice?
Hi Lee,> Massive thanks, I've been staring at this problem for so long I was beginning to go a little stir crazy.No worries. I know how annoying it can be trying to fix these problems. "isBarrier" is the one that usually got me.> Out of interest is there a good explanation of the various isterminator etc flags anywhere?The best I know of is include/llvm/Target/Target.td, which contains a one-line description of each of these flags. Unfortunately it's often still a little ambiguous, or depends on detailed knowledge of LLVM's workings. Tim.
Jakob Stoklund Olesen
2013-Mar-21 18:51 UTC
[LLVMdev] Hit a snag while attempting to write a backend - any advice?
On Mar 21, 2013, at 6:09 AM, Tim Northover <t.p.northover at gmail.com> wrote:> Ah! It looks like the isReturn is to blame then. LLVM is presumably > going through adding an implicit use of any register that will hold a > return value to instructions that will actually return. This would > prevent it from removing instructions that actually define R0 as dead > code (it's "used" by the RET and should certainly be defined by the > time the function does return).This behaviour was removed recently. Now, targets themselves have to add return values as implicit uses on return instructions in their LowerReturn() functions. /jakob