diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 4d1acc9ad1453..b6afb8d5a6de9 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -3642,3 +3642,11 @@ void SparcTargetLowering::insertSSPDeclarations(Module &M) const { if (!Subtarget->isTargetLinux()) return TargetLowering::insertSSPDeclarations(M); } + +void SparcTargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI, + SDNode *Node) const { + assert(MI.getOpcode() == SP::SUBCCrr || MI.getOpcode() == SP::SUBCCri); + // If the result is dead, replace it with %g0. + if (!Node->hasAnyUseOfValue(0)) + MI.getOperand(0).setReg(SP::G0); +} diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h index b7b48decef3d7..15d09bc930975 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -222,7 +222,10 @@ namespace llvm { MachineBasicBlock *expandSelectCC(MachineInstr &MI, MachineBasicBlock *BB, unsigned BROpcode) const; + + void AdjustInstrPostInstrSelection(MachineInstr &MI, + SDNode *Node) const override; }; } // end namespace llvm -#endif // SPARC_ISELLOWERING_H +#endif // LLVM_LIB_TARGET_SPARC_SPARCISELLOWERING_H diff --git a/llvm/lib/Target/Sparc/SparcInstr64Bit.td b/llvm/lib/Target/Sparc/SparcInstr64Bit.td index 189efc32cb266..0823c6cf69e91 100644 --- a/llvm/lib/Target/Sparc/SparcInstr64Bit.td +++ b/llvm/lib/Target/Sparc/SparcInstr64Bit.td @@ -65,6 +65,7 @@ def : Pat<(i64 0), (COPY (i64 G0))>, Requires<[Is64Bit]>; // The ALU instructions want their simm13 operands as i32 immediates. +// FIXME: This is no longer true, they are now pointer-sized. def as_i32imm : SDNodeXFormgetTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32); }]>; @@ -173,8 +174,8 @@ def TLS_ADDXrr : F3_1<2, 0b000000, (outs I64Regs:$rd), (tlsadd i64:$rs1, i64:$rs2, tglobaltlsaddr:$sym))]>; } -def : Pat<(SPcmpicc i64:$a, i64:$b), (CMPrr $a, $b)>; -def : Pat<(SPcmpicc i64:$a, (i64 simm13:$b)), (CMPri $a, (as_i32imm $b))>; +def : Pat<(SPcmpicc i64:$lhs, i64:$rhs), (SUBCCrr $lhs, $rhs)>; +def : Pat<(SPcmpicc i64:$lhs, (i64 simm13:$rhs)), (SUBCCri $lhs, imm:$rhs)>; def : Pat<(i64 (ctpop i64:$src)), (POPCrr $src)>; } // Predicates = [Is64Bit] diff --git a/llvm/lib/Target/Sparc/SparcInstrAliases.td b/llvm/lib/Target/Sparc/SparcInstrAliases.td index 5d247ac641c73..db4c05cf18062 100644 --- a/llvm/lib/Target/Sparc/SparcInstrAliases.td +++ b/llvm/lib/Target/Sparc/SparcInstrAliases.td @@ -413,10 +413,13 @@ defm : reg_cond_alias<"gez", 0b111>; // non-alias form, except for the most obvious and clarifying aliases: cmp, jmp, // call, tst, ret, retl. -// Note: cmp is handled in SparcInstrInfo. -// jmp/call/ret/retl have special case handling for output in +// Note: jmp/call/ret/retl have special case handling for output in // SparcInstPrinter.cpp +// cmp rs1, reg_or_imm -> subcc rs1, reg_or_imm, %g0 +def : InstAlias<"cmp $rs1, $rs2", (SUBCCrr G0, IntRegs:$rs1, IntRegs:$rs2)>; +def : InstAlias<"cmp $rs1, $imm", (SUBCCri G0, IntRegs:$rs1, simm13Op:$imm)>; + // jmp addr -> jmpl addr, %g0 def : InstAlias<"jmp $addr", (JMPLrr G0, MEMrr:$addr), 0>; def : InstAlias<"jmp $addr", (JMPLri G0, MEMri:$addr), 0>; diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index 3e814643f39e6..5e792427cca28 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -222,6 +222,7 @@ def calltarget : Operand { } def simm13Op : Operand { + let OperandType = "OPERAND_IMMEDIATE"; let DecoderMethod = "DecodeSIMM13"; let EncoderMethod = "getSImm13OpValue"; } @@ -829,23 +830,14 @@ defm SUB : F3_12 <"sub" , 0b000100, sub, IntRegs, i32, simm13Op>; let Uses = [ICC], Defs = [ICC] in defm SUBE : F3_12 <"subxcc" , 0b011100, sube, IntRegs, i32, simm13Op>; -let Defs = [ICC] in +let Defs = [ICC], hasPostISelHook = true in defm SUBCC : F3_12 <"subcc", 0b010100, subc, IntRegs, i32, simm13Op>; let Uses = [ICC] in defm SUBC : F3_12np <"subx", 0b001100>; -// cmp (from Section A.3) is a specialized alias for subcc -let Defs = [ICC], rd = 0 in { - def CMPrr : F3_1<2, 0b010100, - (outs), (ins IntRegs:$rs1, IntRegs:$rs2), - "cmp $rs1, $rs2", - [(SPcmpicc i32:$rs1, i32:$rs2)]>; - def CMPri : F3_2<2, 0b010100, - (outs), (ins IntRegs:$rs1, simm13Op:$simm13), - "cmp $rs1, $simm13", - [(SPcmpicc i32:$rs1, (i32 simm13:$simm13))]>; -} +def : Pat<(SPcmpicc i32:$lhs, i32:$rhs), (SUBCCrr $lhs, $rhs)>; +def : Pat<(SPcmpicc i32:$lhs, (i32 simm13:$rhs)), (SUBCCri $lhs, imm:$rhs)>; // Section B.18 - Multiply Instructions, p. 113 let Defs = [Y] in {