I am attempting to lower the selectCC instruction to the instruction set of the backend I'm working on and I cannot seem to find a way to correctly implement this instruction. I know how this instruction should get implemented; I just have yet to find a way to do it. I want the select_cc instruction to be lowered into a comparison followed by a conditional move. I've attempted to use a custom rule pasted below, but it keeps giving me an error about the first argument. What I attempted is as follows: class InstFormat<dag outs, dag ins, string asmstr, list<dag> pattern> : Instruction { let Namespace = "Inst"; dag OutOperandList = outs; dag InOperandList = ins; let Pattern = pattern; let AsmString = asmstr; } def SDTGenTernaryOp : SDTypeProfile<1, 3, [ SDTCisSameAs<0, 1>,SDTCisSameAs<0, 2>, SDTCisSameAs<0, 3> ]>; def cmov_logical : SDNode<"INSTISD::CMOVLOG", SDTGenTernaryOp>; let PrintMethod = "printCCOperand" in def CCOp : Operand<i32>; def CMOVLOG : InstFormat<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, GPR:$TVAL, GPR:$FVAL, CCOp:$cond), "$cond $LHS, $LHS, $RHS\ncmov_logical $dst, $LHS, $TVAL, $FVAL", [(set GPR:$dst, (selectcc GPR:$LHS, GPR:$RHS, GPR:$TVAL, GPR:$FVAL, CCOp:$cond))]>; Maybe I'm approaching this from the wrong way, but I don't think this transformation should be that difficult. Basically I want dst = select $LHS, $RHS, $TVAL, $FVAL, $condOp to be transformed into $condOp tmp, $LHS, $RHS cmov_logical dst, tmp, $TVAL, $FVAL My attempt at doing so with a custom OperationAction also failed. So, what would I need to do to figure out how to implement this correctly? Is there any place you can point me to which shows how to go from a single instruction to multiple consecutive instructions? A function that I can study would be nice since my problem is even though I can look at the other backends, I don't completely understand everything that is going on so I probably overlooked this already. Thanks, Micah Villmow Systems Engineer Advanced Technology & Performance Advanced Micro Devices Inc. 4555 Great America Pkwy, Santa Clara, CA. 95054 P: 408-572-6219 F: 408-572-6596 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080911/94270692/attachment.html>
On Thu, Sep 11, 2008 at 6:14 PM, Villmow, Micah <Micah.Villmow at amd.com> wrote:> I am attempting to lower the selectCC instruction to the instruction set of > the backend I'm working on and I cannot seem to find a way to correctly > implement this instruction. I know how this instruction should get > implemented; I just have yet to find a way to do it. I want the select_cc > instruction to be lowered into a comparison followed by a conditional move."setOperationAction(ISD::SELECT_CC , MVT::Other, Expand);" should do the trick; that will prevent SELECT_CC instructions from being introduced. This one is easy to miss.> def CMOVLOG : InstFormat<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, > GPR:$TVAL, GPR:$FVAL, CCOp:$cond),The condition isn't properly an input... this seems likely to confuse ISel. I'm not sure, though; I'm not really an expert on patterns, and they can mess up in non-obvious ways.> Maybe I'm approaching this from the wrong way, but I don't think this > transformation should be that difficult.If you need to transform a construct into multiple instructions, there are a few different ways; one is a custom lowering, one is a selection pattern, and another is a custom inserter. Stuffing multiple actual instructions into a single target instruction is generally a bad approach. -Eli
Eli, Thanks for the tips. I've been able to get something working using a custom instruction inserter, however, I'm still having the problem of linking together the setcc and the select_cc commands. I want to turn the setcc into a comparison and use the results in the select_cc register. However, the comparison information is in the select_cc instruction and the result of the comparison is in the setcc instruction. What I am trying to figure out is using MachineInstruction/MachineBasicBlock, how I can access the previous/next instruction without having to use an iterator and parse over the whole block. Is this possible? I've put comments in the code below to help understand what I'm attempting to do. case INST::SELECT_CC: // Here we want to write a custom instruction inserter for the // select_cc operation. What we want to do is turn this into // a series of instructions that in the end become a compare // and a cmov_logical { MachineOperand Dst = MI->getOperand(0); MachineOperand TrueVal = MI->getOperand(1); MachineOperand FalseVal = MI->getOperand(2); MachineOperand CCFlag = MI->getOperand(3); CC = (INSTCC::CondCodes)MI->getOperand(3).getImm(); // Here I want to get the destination register of SET_CC instruction and place it as the first addReg TODO(Get setcc destination register); BuildMI(BB, TII.get(INST::CMOVLOG_32),Dst.getReg()).addReg(CCFlag.getImm()).addReg(T rueVal.getReg()).addReg(FalseVal.getReg()); } break; case INST::SET_CC: { MachineOperand Dst = MI->getOperand(0); MachineOperand LHS = MI->getOperand(1); MachineOperand RHS = MI->getOperand(2); // I want to get the CCFlag from the select_CC instruction // and place it in the TII.get() field. BuildMI(BB, TII.get(INST::IL_COMPARE_INSTR), Dst.getReg()).addReg(LHS.getReg()).addReg(RHS.getReg()); } default: }; Again, Thanks for any tips you might be able to share. Micah -----Original Message----- From: llvmdev-bounces at cs.uiuc.edu [mailto:llvmdev-bounces at cs.uiuc.edu] On Behalf Of Eli Friedman Sent: Thursday, September 11, 2008 8:12 PM To: LLVM Developers Mailing List Subject: Re: [LLVMdev] Selection Condition Codes On Thu, Sep 11, 2008 at 6:14 PM, Villmow, Micah <Micah.Villmow at amd.com> wrote:> I am attempting to lower the selectCC instruction to the instructionset of> the backend I'm working on and I cannot seem to find a way tocorrectly> implement this instruction. I know how this instruction should get > implemented; I just have yet to find a way to do it. I want theselect_cc> instruction to be lowered into a comparison followed by a conditionalmove. "setOperationAction(ISD::SELECT_CC , MVT::Other, Expand);" should do the trick; that will prevent SELECT_CC instructions from being introduced. This one is easy to miss.> def CMOVLOG : InstFormat<(outs GPR:$dst), (ins GPR:$LHS, GPR:$RHS, > GPR:$TVAL, GPR:$FVAL, CCOp:$cond),The condition isn't properly an input... this seems likely to confuse ISel. I'm not sure, though; I'm not really an expert on patterns, and they can mess up in non-obvious ways.> Maybe I'm approaching this from the wrong way, but I don't think this > transformation should be that difficult.If you need to transform a construct into multiple instructions, there are a few different ways; one is a custom lowering, one is a selection pattern, and another is a custom inserter. Stuffing multiple actual instructions into a single target instruction is generally a bad approach. -Eli _______________________________________________ LLVM Developers mailing list LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev