diff options
-rw-r--r-- | llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonBitTracker.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp | 24 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfo.td | 29 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td | 186 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp | 32 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp | 6 | ||||
-rw-r--r-- | llvm/test/CodeGen/Hexagon/fsel.ll | 22 |
15 files changed, 139 insertions, 239 deletions
diff --git a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp index 4aa108f1d04..ba223a73afe 100644 --- a/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp +++ b/llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp @@ -1658,13 +1658,9 @@ int HexagonAsmParser::processInstruction(MCInst &Inst, // Translate a "$Rx = CONST32(#imm)" to "$Rx = memw(gp+#LABEL) " case Hexagon::CONST32: - case Hexagon::CONST32_Float_Real: - case Hexagon::CONST32_Int_Real: is32bit = true; // Translate a "$Rx:y = CONST64(#imm)" to "$Rx:y = memd(gp+#LABEL) " - case Hexagon::CONST64_Float_Real: - case Hexagon::CONST64_Int_Real: - + case Hexagon::CONST64: // FIXME: need better way to detect AsmStreamer (upstream removed getKind()) if (!Parser.getStreamer().hasRawTextSupport()) { MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer()); diff --git a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp index 8a3bd222cf0..c95c893c781 100644 --- a/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp +++ b/llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp @@ -283,8 +283,7 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst, } // "$dst = CONST64(#$src1)", - case Hexagon::CONST64_Float_Real: - case Hexagon::CONST64_Int_Real: + case Hexagon::CONST64: if (!OutStreamer->hasRawTextSupport()) { const MCOperand &Imm = MappedInst.getOperand(1); MCSectionSubPair Current = OutStreamer->getCurrentSection(); @@ -303,8 +302,6 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst, } break; case Hexagon::CONST32: - case Hexagon::CONST32_Float_Real: - case Hexagon::CONST32_Int_Real: if (!OutStreamer->hasRawTextSupport()) { MCOperand &Imm = MappedInst.getOperand(1); MCSectionSubPair Current = OutStreamer->getCurrentSection(); @@ -465,21 +462,6 @@ void HexagonAsmPrinter::HexagonProcessInstruction(MCInst &Inst, MappedInst = TmpInst; return; } - case Hexagon::TFRI_f: - MappedInst.setOpcode(Hexagon::A2_tfrsi); - return; - case Hexagon::TFRI_cPt_f: - MappedInst.setOpcode(Hexagon::C2_cmoveit); - return; - case Hexagon::TFRI_cNotPt_f: - MappedInst.setOpcode(Hexagon::C2_cmoveif); - return; - case Hexagon::MUX_ri_f: - MappedInst.setOpcode(Hexagon::C2_muxri); - return; - case Hexagon::MUX_ir_f: - MappedInst.setOpcode(Hexagon::C2_muxir); - return; // Translate a "$Rdd = #imm" to "$Rdd = combine(#[-1,0], #imm)" case Hexagon::A2_tfrpi: { diff --git a/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp b/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp index d1c75b3add9..6de62f13c65 100644 --- a/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp +++ b/llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp @@ -1353,8 +1353,8 @@ bool ConstGeneration::isTfrConst(const MachineInstr &MI) { case Hexagon::A2_tfrpi: case Hexagon::TFR_PdTrue: case Hexagon::TFR_PdFalse: - case Hexagon::CONST32_Int_Real: - case Hexagon::CONST64_Int_Real: + case Hexagon::CONST32: + case Hexagon::CONST64: return true; } return false; @@ -1389,7 +1389,7 @@ unsigned ConstGeneration::genTfrConst(const TargetRegisterClass *RC, int64_t C, return Reg; } - BuildMI(B, At, DL, HII.get(Hexagon::CONST64_Int_Real), Reg) + BuildMI(B, At, DL, HII.get(Hexagon::CONST64), Reg) .addImm(C); return Reg; } diff --git a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp index 78e1dce8a7a..25a8da7560b 100644 --- a/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp +++ b/llvm/lib/Target/Hexagon/HexagonBitTracker.cpp @@ -146,8 +146,7 @@ bool HexagonEvaluator::evaluate(const MachineInstr &MI, // These instructions may be marked as mayLoad, but they are generating // immediate values, so skip them. case CONST32: - case CONST32_Int_Real: - case CONST64_Int_Real: + case CONST64: break; default: return evaluateLoad(MI, Inputs, Outputs); @@ -257,8 +256,7 @@ bool HexagonEvaluator::evaluate(const MachineInstr &MI, case A2_tfrsi: case A2_tfrpi: case CONST32: - case CONST32_Int_Real: - case CONST64_Int_Real: + case CONST64: return rr0(eIMM(im(1), W0), Outputs); case TFR_PdFalse: return rr0(RegisterCell(W0).fill(0, W0, BT::BitValue::Zero), Outputs); diff --git a/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp b/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp index 172df0c8271..c4a0a62e043 100644 --- a/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp +++ b/llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp @@ -1971,14 +1971,13 @@ bool HexagonConstEvaluator::evaluate(const MachineInstr &MI, default: return false; case Hexagon::A2_tfrsi: - case Hexagon::CONST32: case Hexagon::A2_tfrpi: - case Hexagon::CONST32_Int_Real: - case Hexagon::CONST64_Int_Real: + case Hexagon::CONST32: + case Hexagon::CONST64: { const MachineOperand &VO = MI.getOperand(1); - // The operand of CONST32_Int_Real can be a blockaddress, e.g. - // %vreg0<def> = CONST32_Int_Real <blockaddress(@eat, %L)> + // The operand of CONST32 can be a blockaddress, e.g. + // %vreg0<def> = CONST32 <blockaddress(@eat, %L)> // Do this check for all instructions for safety. if (!VO.isImm()) return false; @@ -2326,10 +2325,9 @@ bool HexagonConstEvaluator::rewrite(MachineInstr &MI, const CellMap &Inputs) { default: break; case Hexagon::A2_tfrsi: - case Hexagon::CONST32: case Hexagon::A2_tfrpi: - case Hexagon::CONST32_Int_Real: - case Hexagon::CONST64_Int_Real: + case Hexagon::CONST32: + case Hexagon::CONST64: case Hexagon::TFR_PdTrue: case Hexagon::TFR_PdFalse: return false; @@ -2921,7 +2919,7 @@ bool HexagonConstEvaluator::rewriteHexConstDefs(MachineInstr &MI, .addImm(Hi) .addImm(Lo); } else { - NewD = &HII.get(Hexagon::CONST64_Int_Real); + NewD = &HII.get(Hexagon::CONST64); NewMI = BuildMI(B, At, DL, *NewD, NewR) .addImm(V); } diff --git a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp index 6409852bfcd..a4724433574 100644 --- a/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp +++ b/llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp @@ -628,8 +628,7 @@ void HexagonCopyToCombine::emitConst64(MachineBasicBlock::iterator &InsertPt, int64_t V = HiOperand.getImm(); V = (V << 32) | (0x0ffffffffLL & LoOperand.getImm()); - BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64_Int_Real), - DoubleDestReg) + BuildMI(*BB, InsertPt, DL, TII->get(Hexagon::CONST64), DoubleDestReg) .addImm(V); } diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp index 05773440dac..2530b5f158e 100644 --- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp +++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp @@ -563,7 +563,7 @@ void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB, // Subtract offset from frame pointer. // We use a caller-saved non-parameter register for that. unsigned CallerSavedReg = HRI.getFirstCallerSavedNonParamReg(); - BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::CONST32_Int_Real), + BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::CONST32), CallerSavedReg).addImm(NumBytes); BuildMI(MBB, InsertPt, dl, HII.get(Hexagon::A2_sub), SP) .addReg(SP) diff --git a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp index 608f29184e5..02e08bafb5d 100644 --- a/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -1490,8 +1490,8 @@ bool HexagonHardwareLoops::checkForImmediate(const MachineOperand &MO, case TargetOpcode::COPY: case Hexagon::A2_tfrsi: case Hexagon::A2_tfrpi: - case Hexagon::CONST32_Int_Real: - case Hexagon::CONST64_Int_Real: { + case Hexagon::CONST32: + case Hexagon::CONST64: { // Call recursively to avoid an extra check whether operand(1) is // indeed an immediate (it could be a global address, for example), // plus we can handle COPY at the same time. diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp index ad4aece2905..d6faa4759af 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp @@ -823,7 +823,7 @@ void HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) { Bit <<= ES; } SDValue Ones = CurDAG->getTargetConstant(MV, dl, MVT::i64); - SDNode *OnesReg = CurDAG->getMachineNode(Hexagon::CONST64_Int_Real, dl, + SDNode *OnesReg = CurDAG->getMachineNode(Hexagon::CONST64, dl, MVT::i64, Ones); if (ExVT.getSizeInBits() == 32) { SDNode *And = CurDAG->getMachineNode(Hexagon::A2_andp, dl, MVT::i64, @@ -918,19 +918,15 @@ void HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) { void HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) { SDLoc dl(N); ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); - const APFloat &APF = CN->getValueAPF(); + APInt A = CN->getValueAPF().bitcastToAPInt(); if (N->getValueType(0) == MVT::f32) { - ReplaceNode( - N, CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32, - CurDAG->getTargetConstantFP( - APF.convertToFloat(), dl, MVT::f32))); + SDValue V = CurDAG->getTargetConstant(A.getZExtValue(), dl, MVT::i32); + ReplaceNode(N, CurDAG->getMachineNode(Hexagon::A2_tfrsi, dl, MVT::f32, V)); return; } if (N->getValueType(0) == MVT::f64) { - ReplaceNode( - N, CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64, - CurDAG->getTargetConstantFP( - APF.convertToDouble(), dl, MVT::f64))); + SDValue V = CurDAG->getTargetConstant(A.getZExtValue(), dl, MVT::i64); + ReplaceNode(N, CurDAG->getMachineNode(Hexagon::CONST64, dl, MVT::f64, V)); return; } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp index 92137ec4ad7..b1e237568b1 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp @@ -1301,20 +1301,6 @@ bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const { case Hexagon::TCRETURNr: MI.setDesc(get(Hexagon::J2_jumpr)); return true; - case Hexagon::TFRI_f: - case Hexagon::TFRI_cPt_f: - case Hexagon::TFRI_cNotPt_f: { - unsigned Opx = (Opc == Hexagon::TFRI_f) ? 1 : 2; - APFloat FVal = MI.getOperand(Opx).getFPImm()->getValueAPF(); - APInt IVal = FVal.bitcastToAPInt(); - MI.RemoveOperand(Opx); - unsigned NewOpc = (Opc == Hexagon::TFRI_f) ? Hexagon::A2_tfrsi : - (Opc == Hexagon::TFRI_cPt_f) ? Hexagon::C2_cmoveit : - Hexagon::C2_cmoveif; - MI.setDesc(get(NewOpc)); - MI.addOperand(MachineOperand::CreateImm(IVal.getZExtValue())); - return true; - } } return false; @@ -1942,7 +1928,7 @@ bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const { // object we are going to end up with here for now. // In the future we probably should add isSymbol(), etc. if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() || - MO.isJTI() || MO.isCPI()) + MO.isJTI() || MO.isCPI() || MO.isFPImm()) return true; // If the extendable operand is not 'Immediate' type, the instruction should @@ -3424,14 +3410,6 @@ int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const { if (CondOpcode >= 0) // Valid Conditional opcode/instruction return CondOpcode; - // This switch case will be removed once all the instructions have been - // modified to use relation maps. - switch(Opc) { - case Hexagon::TFRI_f: - return !invertPredicate ? Hexagon::TFRI_cPt_f : - Hexagon::TFRI_cNotPt_f; - } - llvm_unreachable("Unexpected predicable instruction"); } diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td index fda1c988124..094cec65483 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfo.td @@ -4799,29 +4799,18 @@ def LO_GOTREL : ALU32_ri<(outs IntRegs:$dst), (ins globaladdress:$global), "$dst.l = #LO($global@GOTREL)", []>; -// This pattern is incorrect. When we add small data, we should change -// this pattern to use memw(#foo). -// This is for sdata. -let isMoveImm = 1, isAsmParserOnly = 1 in -def CONST32 : CONSTLDInst<(outs IntRegs:$dst), (ins globaladdress:$global), - "$dst = CONST32(#$global)", - [(set (i32 IntRegs:$dst), - (load (HexagonCONST32 tglobaltlsaddr:$global)))]>; - -let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in -def CONST32_Int_Real : CONSTLDInst<(outs IntRegs:$dst), (ins i32imm:$global), - "$dst = CONST32(#$global)", - [(set (i32 IntRegs:$dst), imm:$global) ]>; - -// Map TLS addressses to a CONST32 instruction +let isReMaterializable = 1, isMoveImm = 1 in +def CONST32 : CONSTLDInst<(outs IntRegs:$Rd), (ins i32imm:$v), + "$Rd = CONST32(#$v)", [(set I32:$Rd, imm:$v)]>; + +let isReMaterializable = 1, isMoveImm = 1 in +def CONST64 : CONSTLDInst<(outs DoubleRegs:$Rd), (ins i64imm:$v), + "$Rd = CONST64(#$v)", [(set I64:$Rd, imm:$v)]>; + +// Map TLS addressses to A2_tfrsi. def: Pat<(HexagonCONST32 tglobaltlsaddr:$addr), (A2_tfrsi s16Ext:$addr)>; def: Pat<(HexagonCONST32 bbl:$label), (A2_tfrsi s16Ext:$label)>; -let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in -def CONST64_Int_Real : CONSTLDInst<(outs DoubleRegs:$dst), (ins i64imm:$global), - "$dst = CONST64(#$global)", - [(set (i64 DoubleRegs:$dst), imm:$global)]>; - let hasSideEffects = 0, isReMaterializable = 1, isPseudo = 1, isCodeGenOnly = 1 in def TFR_PdTrue : SInst<(outs PredRegs:$dst), (ins), "", diff --git a/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td b/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td index 8088f4d3671..3d96864a659 100644 --- a/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td +++ b/llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td @@ -11,6 +11,15 @@ // //===----------------------------------------------------------------------===// +def f32ImmPred : PatLeaf<(f32 fpimm:$F)>; +def f64ImmPred : PatLeaf<(f64 fpimm:$F)>; + +def ftoi : SDNodeXForm<fpimm, [{ + APInt I = N->getValueAPF().bitcastToAPInt(); + return CurDAG->getTargetConstant(I.getZExtValue(), SDLoc(N), + MVT::getIntegerVT(I.getBitWidth())); +}]>; + //===----------------------------------------------------------------------===// // XTYPE/MPY //===----------------------------------------------------------------------===// @@ -67,46 +76,6 @@ def C4_fastcorner9_not : T_LOGICAL_2OP<"!fastcorner9", 0b000, 0, 0>, let Inst{20,13,7,4} = 0b1111; } -let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in -def CONST64_Float_Real : LDInst<(outs DoubleRegs:$dst), (ins f64imm:$src1), - "$dst = CONST64(#$src1)", - [(set F64:$dst, fpimm:$src1)]>, - Requires<[HasV5T]>; - -let isReMaterializable = 1, isMoveImm = 1, isAsmParserOnly = 1 in -def CONST32_Float_Real : LDInst<(outs IntRegs:$dst), (ins f32imm:$src1), - "$dst = CONST32(#$src1)", - [(set F32:$dst, fpimm:$src1)]>, - Requires<[HasV5T]>; - -// Transfer immediate float. -// Only works with single precision fp value. -// For double precision, use CONST64_float_real, as 64bit transfer -// can only hold 40-bit values - 32 from const ext + 8 bit immediate. -// Make sure that complexity is more than the CONST32 pattern in -// HexagonInstrInfo.td patterns. -let isExtended = 1, opExtendable = 1, isMoveImm = 1, isReMaterializable = 1, - isPredicable = 1, AddedComplexity = 30, validSubTargets = HasV5SubT, - isCodeGenOnly = 1, isPseudo = 1 in -def TFRI_f : ALU32_ri<(outs IntRegs:$dst), (ins f32Ext:$src1), - "$dst = #$src1", - [(set F32:$dst, fpimm:$src1)]>, - Requires<[HasV5T]>; - -let isExtended = 1, opExtendable = 2, isPredicated = 1, hasSideEffects = 0, - validSubTargets = HasV5SubT, isCodeGenOnly = 1, isPseudo = 1 in -def TFRI_cPt_f : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, f32Ext:$src2), - "if ($src1) $dst = #$src2", []>, - Requires<[HasV5T]>; - -let isExtended = 1, opExtendable = 2, isPredicated = 1, isPredicatedFalse = 1, - hasSideEffects = 0, validSubTargets = HasV5SubT, isPseudo = 1 in -def TFRI_cNotPt_f : ALU32_ri<(outs IntRegs:$dst), - (ins PredRegs:$src1, f32Ext:$src2), - "if (!$src1) $dst = #$src2", []>, - Requires<[HasV5T]>; - def SDTHexagonI32I64: SDTypeProfile<1, 1, [SDTCisVT<0, i32>, SDTCisVT<1, i64>]>; @@ -380,40 +349,40 @@ defm : eq_ordltPats<setolt, F2_sfcmpgt, F2_dfcmpgt>; let Predicates = [HasV5T] in { def: Pat<(i1 (seto F32:$src1, F32:$src2)), (C2_not (F2_sfcmpuo F32:$src2, F32:$src1))>; - def: Pat<(i1 (seto F32:$src1, fpimm:$src2)), - (C2_not (F2_sfcmpuo (TFRI_f fpimm:$src2), F32:$src1))>; + def: Pat<(i1 (seto F32:$src1, f32ImmPred:$src2)), + (C2_not (F2_sfcmpuo (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>; def: Pat<(i1 (seto F64:$src1, F64:$src2)), (C2_not (F2_dfcmpuo F64:$src2, F64:$src1))>; - def: Pat<(i1 (seto F64:$src1, fpimm:$src2)), - (C2_not (F2_dfcmpuo (CONST64_Float_Real fpimm:$src2), F64:$src1))>; + def: Pat<(i1 (seto F64:$src1, f64ImmPred:$src2)), + (C2_not (F2_dfcmpuo (CONST64 (ftoi $src2)), F64:$src1))>; } // Ordered lt. let Predicates = [HasV5T] in { def: Pat<(i1 (setolt F32:$src1, F32:$src2)), (F2_sfcmpgt F32:$src2, F32:$src1)>; - def: Pat<(i1 (setolt F32:$src1, fpimm:$src2)), - (F2_sfcmpgt (f32 (TFRI_f fpimm:$src2)), F32:$src1)>; + def: Pat<(i1 (setolt F32:$src1, f32ImmPred:$src2)), + (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; def: Pat<(i1 (setolt F64:$src1, F64:$src2)), (F2_dfcmpgt F64:$src2, F64:$src1)>; - def: Pat<(i1 (setolt F64:$src1, fpimm:$src2)), - (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>; + def: Pat<(i1 (setolt F64:$src1, f64ImmPred:$src2)), + (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>; } // Unordered lt. let Predicates = [HasV5T] in { def: Pat<(i1 (setult F32:$src1, F32:$src2)), - (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), + (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), (F2_sfcmpgt F32:$src2, F32:$src1))>; - def: Pat<(i1 (setult F32:$src1, fpimm:$src2)), - (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)), - (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1))>; + def: Pat<(i1 (setult F32:$src1, f32ImmPred:$src2)), + (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))), + (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>; def: Pat<(i1 (setult F64:$src1, F64:$src2)), - (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), + (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), (F2_dfcmpgt F64:$src2, F64:$src1))>; - def: Pat<(i1 (setult F64:$src1, fpimm:$src2)), - (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)), - (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1))>; + def: Pat<(i1 (setult F64:$src1, f64ImmPred:$src2)), + (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))), + (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1))>; } // Ordered le. @@ -421,31 +390,31 @@ let Predicates = [HasV5T] in { // rs <= rt -> rt >= rs. def: Pat<(i1 (setole F32:$src1, F32:$src2)), (F2_sfcmpge F32:$src2, F32:$src1)>; - def: Pat<(i1 (setole F32:$src1, fpimm:$src2)), - (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>; + def: Pat<(i1 (setole F32:$src1, f32ImmPred:$src2)), + (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; // Rss <= Rtt -> Rtt >= Rss. def: Pat<(i1 (setole F64:$src1, F64:$src2)), (F2_dfcmpge F64:$src2, F64:$src1)>; - def: Pat<(i1 (setole F64:$src1, fpimm:$src2)), - (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>; + def: Pat<(i1 (setole F64:$src1, f64ImmPred:$src2)), + (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>; } // Unordered le. let Predicates = [HasV5T] in { // rs <= rt -> rt >= rs. def: Pat<(i1 (setule F32:$src1, F32:$src2)), - (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), + (C2_or (F2_sfcmpuo F32:$src1, F32:$src2), (F2_sfcmpge F32:$src2, F32:$src1))>; - def: Pat<(i1 (setule F32:$src1, fpimm:$src2)), - (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)), - (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1))>; + def: Pat<(i1 (setule F32:$src1, f32ImmPred:$src2)), + (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))), + (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1))>; def: Pat<(i1 (setule F64:$src1, F64:$src2)), - (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), + (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), (F2_dfcmpge F64:$src2, F64:$src1))>; - def: Pat<(i1 (setule F64:$src1, fpimm:$src2)), - (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)), - (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1))>; + def: Pat<(i1 (setule F64:$src1, f64ImmPred:$src2)), + (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))), + (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1))>; } // Ordered ne. @@ -454,10 +423,10 @@ let Predicates = [HasV5T] in { (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>; def: Pat<(i1 (setone F64:$src1, F64:$src2)), (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>; - def: Pat<(i1 (setone F32:$src1, fpimm:$src2)), - (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>; - def: Pat<(i1 (setone F64:$src1, fpimm:$src2)), - (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>; + def: Pat<(i1 (setone F32:$src1, f32ImmPred:$src2)), + (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>; + def: Pat<(i1 (setone F64:$src1, f64ImmPred:$src2)), + (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>; } // Unordered ne. @@ -468,13 +437,14 @@ let Predicates = [HasV5T] in { def: Pat<(i1 (setune F64:$src1, F64:$src2)), (C2_or (F2_dfcmpuo F64:$src1, F64:$src2), (C2_not (F2_dfcmpeq F64:$src1, F64:$src2)))>; - def: Pat<(i1 (setune F32:$src1, fpimm:$src2)), - (C2_or (F2_sfcmpuo F32:$src1, (TFRI_f fpimm:$src2)), - (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2))))>; - def: Pat<(i1 (setune F64:$src1, fpimm:$src2)), - (C2_or (F2_dfcmpuo F64:$src1, (CONST64_Float_Real fpimm:$src2)), + def: Pat<(i1 (setune F32:$src1, f32ImmPred:$src2)), + (C2_or (F2_sfcmpuo F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))), + (C2_not (F2_sfcmpeq F32:$src1, + (f32 (A2_tfrsi (ftoi $src2))))))>; + def: Pat<(i1 (setune F64:$src1, f64ImmPred:$src2)), + (C2_or (F2_dfcmpuo F64:$src1, (CONST64 (ftoi $src2))), (C2_not (F2_dfcmpeq F64:$src1, - (CONST64_Float_Real fpimm:$src2))))>; + (CONST64 (ftoi $src2)))))>; } // Besides set[o|u][comparions], we also need set[comparisons]. @@ -482,35 +452,35 @@ let Predicates = [HasV5T] in { // lt. def: Pat<(i1 (setlt F32:$src1, F32:$src2)), (F2_sfcmpgt F32:$src2, F32:$src1)>; - def: Pat<(i1 (setlt F32:$src1, fpimm:$src2)), - (F2_sfcmpgt (TFRI_f fpimm:$src2), F32:$src1)>; + def: Pat<(i1 (setlt F32:$src1, f32ImmPred:$src2)), + (F2_sfcmpgt (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; def: Pat<(i1 (setlt F64:$src1, F64:$src2)), (F2_dfcmpgt F64:$src2, F64:$src1)>; - def: Pat<(i1 (setlt F64:$src1, fpimm:$src2)), - (F2_dfcmpgt (CONST64_Float_Real fpimm:$src2), F64:$src1)>; + def: Pat<(i1 (setlt F64:$src1, f64ImmPred:$src2)), + (F2_dfcmpgt (CONST64 (ftoi $src2)), F64:$src1)>; // le. // rs <= rt -> rt >= rs. def: Pat<(i1 (setle F32:$src1, F32:$src2)), (F2_sfcmpge F32:$src2, F32:$src1)>; - def: Pat<(i1 (setle F32:$src1, fpimm:$src2)), - (F2_sfcmpge (TFRI_f fpimm:$src2), F32:$src1)>; + def: Pat<(i1 (setle F32:$src1, f32ImmPred:$src2)), + (F2_sfcmpge (f32 (A2_tfrsi (ftoi $src2))), F32:$src1)>; // Rss <= Rtt -> Rtt >= Rss. def: Pat<(i1 (setle F64:$src1, F64:$src2)), (F2_dfcmpge F64:$src2, F64:$src1)>; - def: Pat<(i1 (setle F64:$src1, fpimm:$src2)), - (F2_dfcmpge (CONST64_Float_Real fpimm:$src2), F64:$src1)>; + def: Pat<(i1 (setle F64:$src1, f64ImmPred:$src2)), + (F2_dfcmpge (CONST64 (ftoi $src2)), F64:$src1)>; // ne. def: Pat<(i1 (setne F32:$src1, F32:$src2)), (C2_not (F2_sfcmpeq F32:$src1, F32:$src2))>; def: Pat<(i1 (setne F64:$src1, F64:$src2)), (C2_not (F2_dfcmpeq F64:$src1, F64:$src2))>; - def: Pat<(i1 (setne F32:$src1, fpimm:$src2)), - (C2_not (F2_sfcmpeq F32:$src1, (TFRI_f fpimm:$src2)))>; - def: Pat<(i1 (setne F64:$src1, fpimm:$src2)), - (C2_not (F2_dfcmpeq F64:$src1, (CONST64_Float_Real fpimm:$src2)))>; + def: Pat<(i1 (setne F32:$src1, f32ImmPred:$src2)), + (C2_not (F2_sfcmpeq F32:$src1, (f32 (A2_tfrsi (ftoi $src2)))))>; + def: Pat<(i1 (setne F64:$src1, f64ImmPred:$src2)), + (C2_not (F2_dfcmpeq F64:$src1, (CONST64 (ftoi $src2))))>; } // F2 convert template classes: @@ -708,7 +678,7 @@ def F2_sffms: T_sfmpy_acc <1, 0>; def F2_sffma_lib: T_sfmpy_acc <0, 1>; def F2_sffms_lib: T_sfmpy_acc <1, 1>; -def : Pat <(f32 (fma F32:$src2, F32:$src3, F32:$src1)), +def : Pat <(fma F32:$src2, F32:$src3, F32:$src1), (F2_sffma F32:$src1, F32:$src2, F32:$src3)>; // Floating-point fused multiply add w/ additional scaling (2**pu). @@ -735,20 +705,12 @@ def F2_sffma_sc: MInst < let Inst{4-0} = Rx; } -let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 3, - isPseudo = 1, InputType = "imm" in -def MUX_ir_f : ALU32_rr<(outs IntRegs:$dst), - (ins PredRegs:$src1, IntRegs:$src2, f32Ext:$src3), - "$dst = mux($src1, $src2, #$src3)", - [(set F32:$dst, (f32 (select I1:$src1, F32:$src2, fpimm:$src3)))]>, +def: Pat<(select I1:$Pu, F32:$Rs, f32ImmPred:$imm), + (C2_muxir I1:$Pu, F32:$Rs, (ftoi $imm))>, Requires<[HasV5T]>; -let isExtended = 1, isExtentSigned = 1, opExtentBits = 8, opExtendable = 2, - isPseudo = 1, InputType = "imm" in -def MUX_ri_f : ALU32_rr<(outs IntRegs:$dst), - (ins PredRegs:$src1, f32Ext:$src2, IntRegs:$src3), - "$dst = mux($src1, #$src2, $src3)", - [(set F32:$dst, (f32 (select I1:$src1, fpimm:$src2, F32:$src3)))]>, +def: Pat<(select I1:$Pu, f32ImmPred:$imm, F32:$Rt), + (C2_muxri I1:$Pu, (ftoi $imm), F32:$Rt)>, Requires<[HasV5T]>; def: Pat<(select I1:$src1, F32:$src2, F32:$src3), @@ -768,15 +730,15 @@ def: Pat<(select (i1 (setult F64:$src1, F64:$src2)), F64:$src3, F64:$src4), Requires<[HasV5T]>; // Map from p0 = pnot(p0); r0 = select(p0, #i, r1) -// => r0 = MUX_ir_f(p0, #i, r1) -def: Pat<(select (not I1:$src1), fpimm:$src2, F32:$src3), - (MUX_ir_f I1:$src1, F32:$src3, fpimm:$src2)>, +// => r0 = mux(p0, #i, r1) +def: Pat<(select (not I1:$src1), f32ImmPred:$src2, F32:$src3), + (C2_muxir I1:$src1, F32:$src3, (ftoi $src2))>, Requires<[HasV5T]>; // Map from p0 = pnot(p0); r0 = mux(p0, r1, #i) -// => r0 = MUX_ri_f(p0, r1, #i) -def: Pat<(select (not I1:$src1), F32:$src2, fpimm:$src3), - (MUX_ri_f I1:$src1, fpimm:$src3, F32:$src2)>, +// => r0 = mux(p0, r1, #i) +def: Pat<(select (not I1:$src1), F32:$src2, f32ImmPred:$src3), + (C2_muxri I1:$src1, (ftoi $src3), F32:$src2)>, Requires<[HasV5T]>; def: Pat<(i32 (fp_to_sint F64:$src1)), @@ -873,7 +835,7 @@ let Defs = [USR_OVF], Itinerary = S_3op_tc_3x_SLOT23 in { // Classify floating-point value let isFP = 1 in - def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>; +def F2_sfclass : T_TEST_BIT_IMM<"sfclass", 0b111>; let isFP = 1 in def F2_dfclass: ALU64Inst<(outs PredRegs:$Pd), (ins DoubleRegs:$Rss, u5Imm:$u5), @@ -910,8 +872,8 @@ class T_fimm <string mnemonic, RegisterClass RC, bits<4> RegType, bit isNeg> } let hasNewValue = 1, opNewValue = 0 in { -def F2_sfimm_p : T_fimm <"sfmake", IntRegs, 0b0110, 0>; -def F2_sfimm_n : T_fimm <"sfmake", IntRegs, 0b0110, 1>; + def F2_sfimm_p : T_fimm <"sfmake", IntRegs, 0b0110, 0>; + def F2_sfimm_n : T_fimm <"sfmake", IntRegs, 0b0110, 1>; } def F2_dfimm_p : T_fimm <"dfmake", DoubleRegs, 0b1001, 0>; diff --git a/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp b/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp index 5a94cce4ce5..a7c3173dda1 100644 --- a/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // When the compiler is invoked with no small data, for instance, with the -G0 -// command line option, then all CONST32_* opcodes should be broken down into +// command line option, then all CONST* opcodes should be broken down into // appropriate LO and HI instructions. This splitting is done by this pass. // The only reason this is not done in the DAG lowering itself is that there // is no simple way of getting the register allocator to allot the same hard @@ -88,8 +88,7 @@ bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { while (MII != MIE) { MachineInstr &MI = *MII; int Opc = MI.getOpcode(); - if (Opc == Hexagon::CONST32_Int_Real && - MI.getOperand(1).isBlockAddress()) { + if (Opc == Hexagon::CONST32 && MI.getOperand(1).isBlockAddress()) { int DestReg = MI.getOperand(0).getReg(); MachineOperand &Symbol = MI.getOperand(1); @@ -103,40 +102,21 @@ bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) { continue; } - else if (Opc == Hexagon::CONST32_Int_Real || - Opc == Hexagon::CONST32_Float_Real) { + else if (Opc == Hexagon::CONST32) { int DestReg = MI.getOperand(0).getReg(); // We have to convert an FP immediate into its corresponding integer // representation - int64_t ImmValue; - if (Opc == Hexagon::CONST32_Float_Real) { - APFloat Val = MI.getOperand(1).getFPImm()->getValueAPF(); - ImmValue = *Val.bitcastToAPInt().getRawData(); - } - else - ImmValue = MI.getOperand(1).getImm(); - + int64_t ImmValue = MI.getOperand(1).getImm(); BuildMI(*MBB, MII, MI.getDebugLoc(), TII->get(Hexagon::A2_tfrsi), DestReg) .addImm(ImmValue); MII = MBB->erase(&MI); continue; } - else if (Opc == Hexagon::CONST64_Int_Real || - Opc == Hexagon::CONST64_Float_Real) { + else if (Opc == Hexagon::CONST64) { int DestReg = MI.getOperand(0).getReg(); - - // We have to convert an FP immediate into its corresponding integer - // representation - int64_t ImmValue; - if (Opc == Hexagon::CONST64_Float_Real) { - APFloat Val = MI.getOperand(1).getFPImm()->getValueAPF(); - ImmValue = *Val.bitcastToAPInt().getRawData(); - } - else - ImmValue = MI.getOperand(1).getImm(); - + int64_t ImmValue = MI.getOperand(1).getImm(); unsigned DestLo = TRI->getSubReg(DestReg, Hexagon::subreg_loreg); unsigned DestHi = TRI->getSubReg(DestReg, Hexagon::subreg_hireg); diff --git a/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp b/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp index 25b2affa2f0..7ca80b0b1f2 100644 --- a/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp +++ b/llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp @@ -170,7 +170,7 @@ bool HexagonSplitDoubleRegs::isFixedInstr(const MachineInstr *MI) const { case Hexagon::A4_combineii: case Hexagon::A4_combineri: case Hexagon::A2_combinew: - case Hexagon::CONST64_Int_Real: + case Hexagon::CONST64: case Hexagon::A2_sxtw: @@ -319,7 +319,7 @@ int32_t HexagonSplitDoubleRegs::profit(const MachineInstr *MI) const { return 2; case Hexagon::A2_tfrpi: - case Hexagon::CONST64_Int_Real: { + case Hexagon::CONST64: { uint64_t D = MI->getOperand(1).getImm(); unsigned Lo = D & 0xFFFFFFFFULL; unsigned Hi = D >> 32; @@ -995,7 +995,7 @@ bool HexagonSplitDoubleRegs::splitInstr(MachineInstr *MI, break; case A2_tfrpi: - case CONST64_Int_Real: + case CONST64: splitImmediate(MI, PairMap); Split = true; break; diff --git a/llvm/test/CodeGen/Hexagon/fsel.ll b/llvm/test/CodeGen/Hexagon/fsel.ll new file mode 100644 index 00000000000..247249da50b --- /dev/null +++ b/llvm/test/CodeGen/Hexagon/fsel.ll @@ -0,0 +1,22 @@ +; RUN: llc -march=hexagon -O0 < %s | FileCheck %s + +; CHECK-LABEL: danny: +; CHECK: mux(p0, r1, ##1065353216) + +define float @danny(i32 %x, float %f) #0 { + %t = icmp sgt i32 %x, 0 + %u = select i1 %t, float %f, float 1.0 + ret float %u +} + +; CHECK-LABEL: sammy: +; CHECK: mux(p0, ##1069547520, r1) + +define float @sammy(i32 %x, float %f) #0 { + %t = icmp sgt i32 %x, 0 + %u = select i1 %t, float 1.5, float %f + ret float %u +} + +attributes #0 = { nounwind "target-cpu"="hexagonv5" } + |