summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp6
-rw-r--r--llvm/lib/Target/Hexagon/HexagonAsmPrinter.cpp20
-rw-r--r--llvm/lib/Target/Hexagon/HexagonBitSimplify.cpp6
-rw-r--r--llvm/lib/Target/Hexagon/HexagonBitTracker.cpp6
-rw-r--r--llvm/lib/Target/Hexagon/HexagonConstPropagation.cpp16
-rw-r--r--llvm/lib/Target/Hexagon/HexagonCopyToCombine.cpp3
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp2
-rw-r--r--llvm/lib/Target/Hexagon/HexagonHardwareLoops.cpp4
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp16
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp24
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfo.td29
-rw-r--r--llvm/lib/Target/Hexagon/HexagonInstrInfoV5.td186
-rw-r--r--llvm/lib/Target/Hexagon/HexagonSplitConst32AndConst64.cpp32
-rw-r--r--llvm/lib/Target/Hexagon/HexagonSplitDouble.cpp6
-rw-r--r--llvm/test/CodeGen/Hexagon/fsel.ll22
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" }
+
OpenPOWER on IntegriCloud