Hi, I'm having some trouble wirting an instruction in the X86 backend. I made a new intrinsic and I wrote a custom inserter for my intrinsic in the X86 backend. Everything works fine, except for one instruction that I can't find how to write. I want to add this instruction in one of my machine basic block: mov [rdi], 0 How can I achieve that with the LLVM api? I tried several stuff, but none works :( Cheers
Hi,> I want to add this instruction in one of my machine basic block: mov [rdi], 0 > How can I achieve that with the LLVM api? I tried several stuff, but none works :(I find the best way to do this when I'm unsure is to get the llvm-mc tool to assemble my instruction and copy what it produces. Your instruction is actually ambiguous though: you need to say what size you want the store to be. I'll assume 32-bit: $ echo "mov dword ptr [rdi], 0" | llvm-mc -x86-asm-syntax=intel -output-asm-variant=1 -show-inst mov dword ptr [rdi], 0 ## <MCInst #1611 MOV32mi ## <MCOperand Reg:39> ## <MCOperand Imm:1> ## <MCOperand Reg:0> ## <MCOperand Imm:0> ## <MCOperand Reg:0> ## <MCOperand Imm:0>> Now, that looks complicated, but x86 has uniform memory addressing-modes: those first 5 operands are just specifying that address and you only have to learn about them once; and the last operand is the "0" you've written (try playing around a bit with the input). As for the addressing, the meaning of each operand is given at the top of lib/Target/X86/X86BaseInfo.h: 0 == Base, 1 == Scale, 2 == Index, 3 == Disp, 4 == Segment. Cheers. Tim.
>> I want to add this instruction in one of my machine basic block: mov [rdi], 0 >> How can I achieve that with the LLVM api? I tried several stuff, but none works :(Just realised I didn't actually answer your question after that explanation. Something like this should work: BuildMI(MBB, MBBI, dl, TII.get(X86::MOV32mi)) .addReg(X86::RDI).addImm(1).addReg(0).addImm(0).addReg(0) .addImm(0); All the operands are outside the BuildMI because the register operand you often put inside is actually one the function defines, but this store doesn't actually change RDI itself. (You may want to add a RegState::Kill if that's the last use of RDI). Cheers. Tim.
Hum, in fact, I'm still a bit lost ;) It seems to works in -O0, but in -O1, -O2 and -O3, I got this error (+ the dump of the function): # Machine code for function foo: Post SSA Function Live Ins: %RDI in %vreg7 BB#0: derived from LLVM BB %entry Live Ins: %RDI %vreg7<def> = COPY %RDI; GR64:%vreg7 %vreg1<def> = MOV64rm %vreg7, 1, %noreg, 8, %noreg; mem:LD8[%args.03](tbaa=<badref>) GR64:%vreg1,%vreg7 TEST64rr %vreg1, %vreg1, %EFLAGS<imp-def>; GR64:%vreg1 JE_4 <BB#3>, %EFLAGS<imp-use,kill> Successors according to CFG: BB#3(12) BB#1(20) BB#1: Predecessors according to CFG: BB#0 %vreg9<def> = COPY %vreg1; GR64:%vreg9,%vreg1 %vreg10<def> = COPY %vreg7; GR64:%vreg10,%vreg7 %vreg0<def> = LEA64r %vreg7, 1, %noreg, 8, %noreg; GR64:%vreg0,%vreg7 %vreg11<def> = COPY %vreg0; GR64:%vreg11,%vreg0 Successors according to CFG: BB#2 BB#2: derived from LLVM BB %while.body Predecessors according to CFG: BB#2 BB#1 %vreg4<def> = COPY %vreg11; GR64:%vreg4,%vreg11 %vreg3<def> = COPY %vreg10; GR64:%vreg3,%vreg10 %vreg2<def> = COPY %vreg9; GR64:%vreg2,%vreg9 ADJCALLSTACKDOWN64 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use> %RDI<def> = COPY %vreg2; GR64:%vreg2 CALL64pcrel32 <ga:@puts>, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, ... ADJCALLSTACKUP64 0, 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use> %vreg6<def> = MOV64rm %vreg3, 1, %noreg, 16, %noreg; mem:LD8[%args.0](tbaa=<badref>) GR64:%vreg6,%vreg3 %vreg5<def> = COPY %vreg3; GR64:%vreg5,%vreg3 %vreg5<def,tied1> = ADD64ri8 %vreg5<tied0>, 16, %EFLAGS<imp-def,dead>; GR64:%vreg5 TEST64rr %vreg6, %vreg6, %EFLAGS<imp-def>; GR64:%vreg6 %vreg9<def> = COPY %vreg6; GR64:%vreg9,%vreg6 %vreg10<def> = COPY %vreg4; GR64:%vreg10,%vreg4 %vreg11<def> = COPY %vreg5; GR64:%vreg11,%vreg5 JNE_4 <BB#2>, %EFLAGS<imp-use,kill> JMP_4 <BB#3> Successors according to CFG: BB#3(4) BB#2(124) BB#3: derived from LLVM BB %while.end Predecessors according to CFG: BB#0 BB#2 Successors according to CFG: BB#4 BB#4: derived from LLVM BB %while.end Predecessors according to CFG: BB#3 BB#5 CMP64rr %RDI, %RBP<kill>, %EFLAGS<imp-def> JE_4 <BB#6>, %EFLAGS<imp-use,kill> Successors according to CFG: BB#6 BB#5 BB#5: derived from LLVM BB %while.end Predecessors according to CFG: BB#4 MOV32mi %RDI<kill>, 1, %noreg, 0, %noreg, 0 JMP_4 <BB#4> Successors according to CFG: BB#4 BB#6: derived from LLVM BB %while.end Predecessors according to CFG: BB#4 RETQ # End machine code for function foo. *** Bad machine code: Using an undefined physical register *** - function: foo - basic block: BB#4 while.end (0x46c4840) - instruction: CMP64rr %RDI, %RBP<kill>, %EFLAGS<imp-def> - operand 0: %RDI *** Bad machine code: Using an undefined physical register *** - function: foo - basic block: BB#4 while.end (0x46c4840) - instruction: CMP64rr %RDI, %RBP<kill>, %EFLAGS<imp-def> - operand 1: %RBP<kill> *** Bad machine code: Using an undefined physical register *** - function: foo - basic block: BB#5 while.end (0x46c48f0) - instruction: MOV32mi %RDI<kill>, 1, %noreg, 0, %noreg, 0 - operand 0: %RDI<kill> Cheers
Hi Julien,> On Oct 28, 2014, at 2:14 AM, Rinaldini Julien <julien.rinaldini at heig-vd.ch> wrote: > > Hum, in fact, I'm still a bit lost ;) > > It seems to works in -O0, but in -O1, -O2 and -O3, I got this error (+ the dump of the function): > > # Machine code for function foo: Post SSA > Function Live Ins: %RDI in %vreg7 > > BB#0: derived from LLVM BB %entry > Live Ins: %RDI > %vreg7<def> = COPY %RDI; GR64:%vreg7 > %vreg1<def> = MOV64rm %vreg7, 1, %noreg, 8, %noreg; mem:LD8[%args.03](tbaa=<badref>) GR64:%vreg1,%vreg7 > TEST64rr %vreg1, %vreg1, %EFLAGS<imp-def>; GR64:%vreg1 > JE_4 <BB#3>, %EFLAGS<imp-use,kill> > Successors according to CFG: BB#3(12) BB#1(20) > > BB#1: > Predecessors according to CFG: BB#0 > %vreg9<def> = COPY %vreg1; GR64:%vreg9,%vreg1 > %vreg10<def> = COPY %vreg7; GR64:%vreg10,%vreg7 > %vreg0<def> = LEA64r %vreg7, 1, %noreg, 8, %noreg; GR64:%vreg0,%vreg7 > %vreg11<def> = COPY %vreg0; GR64:%vreg11,%vreg0 > Successors according to CFG: BB#2 > > BB#2: derived from LLVM BB %while.body > Predecessors according to CFG: BB#2 BB#1 > %vreg4<def> = COPY %vreg11; GR64:%vreg4,%vreg11 > %vreg3<def> = COPY %vreg10; GR64:%vreg3,%vreg10 > %vreg2<def> = COPY %vreg9; GR64:%vreg2,%vreg9 > ADJCALLSTACKDOWN64 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use> > %RDI<def> = COPY %vreg2; GR64:%vreg2 > CALL64pcrel32 <ga:@puts>, <regmask>, %RSP<imp-use>, %RDI<imp-use>, %RSP<imp-def>, ... > ADJCALLSTACKUP64 0, 0, %RSP<imp-def>, %EFLAGS<imp-def,dead>, %RSP<imp-use> > %vreg6<def> = MOV64rm %vreg3, 1, %noreg, 16, %noreg; mem:LD8[%args.0](tbaa=<badref>) GR64:%vreg6,%vreg3 > %vreg5<def> = COPY %vreg3; GR64:%vreg5,%vreg3 > %vreg5<def,tied1> = ADD64ri8 %vreg5<tied0>, 16, %EFLAGS<imp-def,dead>; GR64:%vreg5 > TEST64rr %vreg6, %vreg6, %EFLAGS<imp-def>; GR64:%vreg6 > %vreg9<def> = COPY %vreg6; GR64:%vreg9,%vreg6 > %vreg10<def> = COPY %vreg4; GR64:%vreg10,%vreg4 > %vreg11<def> = COPY %vreg5; GR64:%vreg11,%vreg5 > JNE_4 <BB#2>, %EFLAGS<imp-use,kill> > JMP_4 <BB#3> > Successors according to CFG: BB#3(4) BB#2(124) > > BB#3: derived from LLVM BB %while.end > Predecessors according to CFG: BB#0 BB#2 > Successors according to CFG: BB#4 > > BB#4: derived from LLVM BB %while.end > Predecessors according to CFG: BB#3 BB#5 > CMP64rr %RDI, %RBP<kill>, %EFLAGS<imp-def> > JE_4 <BB#6>, %EFLAGS<imp-use,kill> > Successors according to CFG: BB#6 BB#5 > > BB#5: derived from LLVM BB %while.end > Predecessors according to CFG: BB#4 > MOV32mi %RDI<kill>, 1, %noreg, 0, %noreg, 0Your problem is that kill flag on RDI. Indeed, this is not the last use of RDI in your case and because you set this flag, when jumping to BB#4, the compiler thinks that RDI is not defined. Also, I am not sure what you are trying to achieve, but are you sure you always want to use RDI? In this case, should it be vreg7 for instance? -Quentin> JMP_4 <BB#4> > Successors according to CFG: BB#4 > > BB#6: derived from LLVM BB %while.end > Predecessors according to CFG: BB#4 > RETQ > > # End machine code for function foo. > > *** Bad machine code: Using an undefined physical register *** > - function: foo > - basic block: BB#4 while.end (0x46c4840) > - instruction: CMP64rr %RDI, %RBP<kill>, %EFLAGS<imp-def> > - operand 0: %RDI > > *** Bad machine code: Using an undefined physical register *** > - function: foo > - basic block: BB#4 while.end (0x46c4840) > - instruction: CMP64rr %RDI, %RBP<kill>, %EFLAGS<imp-def> > - operand 1: %RBP<kill> > > *** Bad machine code: Using an undefined physical register *** > - function: foo > - basic block: BB#5 while.end (0x46c48f0) > - instruction: MOV32mi %RDI<kill>, 1, %noreg, 0, %noreg, 0 > - operand 0: %RDI<kill> > > > Cheers > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reasonably Related Threads
- [LLVMdev] System call miscompilation using the fast register allocator
- [LLVMdev] RegisterCoalescing pass crashes with ImplicitDef registers
- [LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.
- [LLVMdev] Strong vs. default phi elimination and single-reg classes
- [LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.