summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
authorDaniel Sanders <daniel_l_sanders@apple.com>2017-10-13 21:28:03 +0000
committerDaniel Sanders <daniel_l_sanders@apple.com>2017-10-13 21:28:03 +0000
commit11300cead8fd7ecc31f71cdf493e69e4c66a5e82 (patch)
treeec96a8c5ee9a0e7d9094a46e9e13d53555ae969d /llvm/include
parent3b87939604dbbac3dbe7a60927fb53dc4a7fb3da (diff)
downloadbcm5719-llvm-11300cead8fd7ecc31f71cdf493e69e4c66a5e82.tar.gz
bcm5719-llvm-11300cead8fd7ecc31f71cdf493e69e4c66a5e82.zip
[globalisel][tablegen] Add support for fpimm and import of APInt/APFloat based ImmLeaf.
Summary: There's only a tablegen testcase for IntImmLeaf and not a CodeGen one because the relevant rules are rejected for other reasons at the moment. On AArch64, it's because there's an SDNodeXForm attached to the operand. On X86, it's because the rule either emits multiple instructions or has another predicate using PatFrag which cannot easily be supported at the same time. Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar Reviewed By: qcolombet Subscribers: aemerson, javed.absar, igorb, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D36569 llvm-svn: 315761
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h20
-rw-r--r--llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h49
-rw-r--r--llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td2
3 files changed, 61 insertions, 10 deletions
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
index 9f7b9da8735..08c813a79c2 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -26,6 +26,8 @@
namespace llvm {
+class APInt;
+class APFloat;
class LLT;
class MachineInstr;
class MachineInstrBuilder;
@@ -96,7 +98,15 @@ enum {
/// Check an immediate predicate on the specified instruction
/// - InsnID - Instruction ID
/// - The predicate to test
- GIM_CheckImmPredicate,
+ GIM_CheckI64ImmPredicate,
+ /// Check an immediate predicate on the specified instruction via an APInt.
+ /// - InsnID - Instruction ID
+ /// - The predicate to test
+ GIM_CheckAPIntImmPredicate,
+ /// Check a floating point immediate predicate on the specified instruction.
+ /// - InsnID - Instruction ID
+ /// - The predicate to test
+ GIM_CheckAPFloatImmPredicate,
/// Check the type for the specified operand
/// - InsnID - Instruction ID
@@ -226,7 +236,9 @@ enum {
/// Provides the logic to select generic machine instructions.
class InstructionSelector {
public:
- using ImmediatePredicateFn = bool (*)(int64_t);
+ using I64ImmediatePredicateFn = bool (*)(int64_t);
+ using APIntImmediatePredicateFn = bool (*)(const APInt &);
+ using APFloatImmediatePredicateFn = bool (*)(const APFloat &);
virtual ~InstructionSelector() = default;
@@ -259,7 +271,9 @@ public:
struct MatcherInfoTy {
const LLT *TypeObjects;
const PredicateBitset *FeatureBitsets;
- const ImmediatePredicateFn *ImmPredicateFns;
+ const I64ImmediatePredicateFn *I64ImmPredicateFns;
+ const APIntImmediatePredicateFn *APIntImmPredicateFns;
+ const APFloatImmediatePredicateFn *APFloatImmPredicateFns;
const std::vector<ComplexMatcherMemFn> ComplexPredicates;
};
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
index a43c663bd6e..6bab06dca2c 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h
@@ -36,7 +36,9 @@ namespace llvm {
/// GlobalISel PatFrag Predicates
enum {
- GIPFP_Invalid,
+ GIPFP_I64_Invalid = 0,
+ GIPFP_APInt_Invalid = 0,
+ GIPFP_APFloat_Invalid = 0,
};
template <class TgtInstructionSelector, class PredicateBitset,
@@ -149,16 +151,15 @@ bool InstructionSelector::executeMatchTable(
}
break;
}
-
- case GIM_CheckImmPredicate: {
+ case GIM_CheckI64ImmPredicate: {
int64_t InsnID = MatchTable[CurrentIdx++];
int64_t Predicate = MatchTable[CurrentIdx++];
- DEBUG(dbgs() << CurrentIdx << ": GIM_CheckImmPredicate(MIs[" << InsnID
+ DEBUG(dbgs() << CurrentIdx << ": GIM_CheckI64ImmPredicate(MIs[" << InsnID
<< "], Predicate=" << Predicate << ")\n");
assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_CONSTANT &&
"Expected G_CONSTANT");
- assert(Predicate > GIPFP_Invalid && "Expected a valid predicate");
+ assert(Predicate > GIPFP_I64_Invalid && "Expected a valid predicate");
int64_t Value = 0;
if (State.MIs[InsnID]->getOperand(1).isCImm())
Value = State.MIs[InsnID]->getOperand(1).getCImm()->getSExtValue();
@@ -167,7 +168,43 @@ bool InstructionSelector::executeMatchTable(
else
llvm_unreachable("Expected Imm or CImm operand");
- if (!MatcherInfo.ImmPredicateFns[Predicate](Value))
+ if (!MatcherInfo.I64ImmPredicateFns[Predicate](Value))
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
+ case GIM_CheckAPIntImmPredicate: {
+ int64_t InsnID = MatchTable[CurrentIdx++];
+ int64_t Predicate = MatchTable[CurrentIdx++];
+ DEBUG(dbgs() << CurrentIdx << ": GIM_CheckAPIntImmPredicate(MIs["
+ << InsnID << "], Predicate=" << Predicate << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ assert(State.MIs[InsnID]->getOpcode() && "Expected G_CONSTANT");
+ assert(Predicate > GIPFP_APInt_Invalid && "Expected a valid predicate");
+ APInt Value;
+ if (State.MIs[InsnID]->getOperand(1).isCImm())
+ Value = State.MIs[InsnID]->getOperand(1).getCImm()->getValue();
+ else
+ llvm_unreachable("Expected Imm or CImm operand");
+
+ if (!MatcherInfo.APIntImmPredicateFns[Predicate](Value))
+ if (handleReject() == RejectAndGiveUp)
+ return false;
+ break;
+ }
+ case GIM_CheckAPFloatImmPredicate: {
+ int64_t InsnID = MatchTable[CurrentIdx++];
+ int64_t Predicate = MatchTable[CurrentIdx++];
+ DEBUG(dbgs() << CurrentIdx << ": GIM_CheckAPFloatImmPredicate(MIs[" << InsnID
+ << "], Predicate=" << Predicate << ")\n");
+ assert(State.MIs[InsnID] != nullptr && "Used insn before defined");
+ assert(State.MIs[InsnID]->getOpcode() == TargetOpcode::G_FCONSTANT &&
+ "Expected G_FCONSTANT");
+ assert(State.MIs[InsnID]->getOperand(1).isFPImm() && "Expected FPImm operand");
+ assert(Predicate > GIPFP_APFloat_Invalid && "Expected a valid predicate");
+ APFloat Value = State.MIs[InsnID]->getOperand(1).getFPImm()->getValueAPF();
+
+ if (!MatcherInfo.APFloatImmPredicateFns[Predicate](Value))
if (handleReject() == RejectAndGiveUp)
return false;
break;
diff --git a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
index f6da58ba796..96245b251f9 100644
--- a/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
+++ b/llvm/include/llvm/Target/GlobalISel/SelectionDAGCompat.td
@@ -34,7 +34,7 @@ def : GINodeEquiv<G_BITCAST, bitconvert>;
// G_INTTOPTR - SelectionDAG has no equivalent.
// G_PTRTOINT - SelectionDAG has no equivalent.
def : GINodeEquiv<G_CONSTANT, imm>;
-// G_FCONSTANT - Not needed since constants aren't operators.
+def : GINodeEquiv<G_FCONSTANT, fpimm>;
def : GINodeEquiv<G_ADD, add>;
def : GINodeEquiv<G_SUB, sub>;
def : GINodeEquiv<G_MUL, mul>;
OpenPOWER on IntegriCloud