summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2016-11-09 23:53:43 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2016-11-09 23:53:43 +0000
commit32ab3a817d4d8ae20e868e8966ceef1511a88d03 (patch)
tree9ca9b77b41506c562b0e2c4d4cbcbc790f1f4960
parentab3f96cb21ed0bb5697bb5f92f3630d89e1e97de (diff)
downloadbcm5719-llvm-32ab3a817d4d8ae20e868e8966ceef1511a88d03.tar.gz
bcm5719-llvm-32ab3a817d4d8ae20e868e8966ceef1511a88d03.zip
Re-apply r286384, "X86: Introduce the "relocImm" ComplexPattern, which represents a relocatable immediate.", with a fix for 32-bit x86.
Teach X86InstrInfo::analyzeCompare() not to crash on CMP and SUB instructions that take a global address operand. llvm-svn: 286420
-rw-r--r--llvm/include/llvm/Target/TargetSelectionDAG.td4
-rw-r--r--llvm/lib/Target/X86/X86ISelDAGToDAG.cpp22
-rw-r--r--llvm/lib/Target/X86/X86InstrCompiler.td47
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.cpp4
-rw-r--r--llvm/lib/Target/X86/X86InstrInfo.td14
-rw-r--r--llvm/test/CodeGen/X86/compare-global.ll22
-rw-r--r--llvm/utils/TableGen/CodeGenDAGPatterns.cpp7
-rw-r--r--llvm/utils/TableGen/CodeGenTarget.cpp10
-rw-r--r--llvm/utils/TableGen/CodeGenTarget.h3
9 files changed, 73 insertions, 60 deletions
diff --git a/llvm/include/llvm/Target/TargetSelectionDAG.td b/llvm/include/llvm/Target/TargetSelectionDAG.td
index d4815c9f760..4ddf7d77a23 100644
--- a/llvm/include/llvm/Target/TargetSelectionDAG.td
+++ b/llvm/include/llvm/Target/TargetSelectionDAG.td
@@ -1165,10 +1165,12 @@ class Pat<dag pattern, dag result> : Pattern<pattern, [result]>;
// e.g. X86 addressing mode - def addr : ComplexPattern<4, "SelectAddr", [add]>;
//
class ComplexPattern<ValueType ty, int numops, string fn,
- list<SDNode> roots = [], list<SDNodeProperty> props = []> {
+ list<SDNode> roots = [], list<SDNodeProperty> props = [],
+ int complexity = -1> {
ValueType Ty = ty;
int NumOperands = numops;
string SelectFunc = fn;
list<SDNode> RootNodes = roots;
list<SDNodeProperty> Properties = props;
+ int Complexity = complexity;
}
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
index e9d0f67560d..516d067d489 100644
--- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
+++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
@@ -228,6 +228,7 @@ namespace {
SDValue &Index, SDValue &Disp,
SDValue &Segment,
SDValue &NodeWithChain);
+ bool selectRelocImm(SDValue N, SDValue &Op);
bool tryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
@@ -1704,6 +1705,27 @@ bool X86DAGToDAGISel::selectTLSADDRAddr(SDValue N, SDValue &Base,
return true;
}
+bool X86DAGToDAGISel::selectRelocImm(SDValue N, SDValue &Op) {
+ if (auto *CN = dyn_cast<ConstantSDNode>(N)) {
+ Op = CurDAG->getTargetConstant(CN->getAPIntValue(), SDLoc(CN),
+ N.getValueType());
+ return true;
+ }
+
+ if (N.getOpcode() != X86ISD::Wrapper)
+ return false;
+
+ unsigned Opc = N.getOperand(0)->getOpcode();
+ if (Opc == ISD::TargetConstantPool || Opc == ISD::TargetJumpTable ||
+ Opc == ISD::TargetExternalSymbol || Opc == ISD::TargetGlobalAddress ||
+ Opc == ISD::TargetGlobalTLSAddress || Opc == ISD::MCSymbol ||
+ Opc == ISD::TargetBlockAddress) {
+ Op = N.getOperand(0);
+ return true;
+ }
+
+ return false;
+}
bool X86DAGToDAGISel::tryFoldLoad(SDNode *P, SDValue N,
SDValue &Base, SDValue &Scale,
diff --git a/llvm/lib/Target/X86/X86InstrCompiler.td b/llvm/lib/Target/X86/X86InstrCompiler.td
index 4264b5b5023..e5cd1ef3281 100644
--- a/llvm/lib/Target/X86/X86InstrCompiler.td
+++ b/llvm/lib/Target/X86/X86InstrCompiler.td
@@ -1025,53 +1025,6 @@ def : Pat<(store (i32 -1), addr:$dst), (OR32mi8 addr:$dst, -1)>;
def : Pat<(store (i64 -1), addr:$dst), (OR64mi8 addr:$dst, -1)>;
}
-// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable
-def : Pat<(i32 (X86Wrapper tconstpool :$dst)), (MOV32ri tconstpool :$dst)>;
-def : Pat<(i32 (X86Wrapper tjumptable :$dst)), (MOV32ri tjumptable :$dst)>;
-def : Pat<(i32 (X86Wrapper tglobaltlsaddr:$dst)),(MOV32ri tglobaltlsaddr:$dst)>;
-def : Pat<(i32 (X86Wrapper tglobaladdr :$dst)), (MOV32ri tglobaladdr :$dst)>;
-def : Pat<(i32 (X86Wrapper texternalsym:$dst)), (MOV32ri texternalsym:$dst)>;
-def : Pat<(i32 (X86Wrapper mcsym:$dst)), (MOV32ri mcsym:$dst)>;
-def : Pat<(i32 (X86Wrapper tblockaddress:$dst)), (MOV32ri tblockaddress:$dst)>;
-
-def : Pat<(add GR32:$src1, (X86Wrapper tconstpool:$src2)),
- (ADD32ri GR32:$src1, tconstpool:$src2)>;
-def : Pat<(add GR32:$src1, (X86Wrapper tjumptable:$src2)),
- (ADD32ri GR32:$src1, tjumptable:$src2)>;
-def : Pat<(add GR32:$src1, (X86Wrapper tglobaladdr :$src2)),
- (ADD32ri GR32:$src1, tglobaladdr:$src2)>;
-def : Pat<(add GR32:$src1, (X86Wrapper texternalsym:$src2)),
- (ADD32ri GR32:$src1, texternalsym:$src2)>;
-def : Pat<(add GR32:$src1, (X86Wrapper mcsym:$src2)),
- (ADD32ri GR32:$src1, mcsym:$src2)>;
-def : Pat<(add GR32:$src1, (X86Wrapper tblockaddress:$src2)),
- (ADD32ri GR32:$src1, tblockaddress:$src2)>;
-
-def : Pat<(store (i32 (X86Wrapper tglobaladdr:$src)), addr:$dst),
- (MOV32mi addr:$dst, tglobaladdr:$src)>;
-def : Pat<(store (i32 (X86Wrapper texternalsym:$src)), addr:$dst),
- (MOV32mi addr:$dst, texternalsym:$src)>;
-def : Pat<(store (i32 (X86Wrapper mcsym:$src)), addr:$dst),
- (MOV32mi addr:$dst, mcsym:$src)>;
-def : Pat<(store (i32 (X86Wrapper tblockaddress:$src)), addr:$dst),
- (MOV32mi addr:$dst, tblockaddress:$src)>;
-
-// ConstantPool GlobalAddress, ExternalSymbol, and JumpTable when not in small
-// code model mode, should use 'movabs'. FIXME: This is really a hack, the
-// 'movabs' predicate should handle this sort of thing.
-def : Pat<(i64 (X86Wrapper tconstpool :$dst)),
- (MOV64ri tconstpool :$dst)>, Requires<[FarData]>;
-def : Pat<(i64 (X86Wrapper tjumptable :$dst)),
- (MOV64ri tjumptable :$dst)>, Requires<[FarData]>;
-def : Pat<(i64 (X86Wrapper tglobaladdr :$dst)),
- (MOV64ri tglobaladdr :$dst)>, Requires<[FarData]>;
-def : Pat<(i64 (X86Wrapper texternalsym:$dst)),
- (MOV64ri texternalsym:$dst)>, Requires<[FarData]>;
-def : Pat<(i64 (X86Wrapper mcsym:$dst)),
- (MOV64ri mcsym:$dst)>, Requires<[FarData]>;
-def : Pat<(i64 (X86Wrapper tblockaddress:$dst)),
- (MOV64ri tblockaddress:$dst)>, Requires<[FarData]>;
-
// In kernel code model, we can get the address of a label
// into a register with 'movq'. FIXME: This is a hack, the 'imm' predicate of
// the MOV64ri32 should accept these.
diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp
index fd082097f9d..cb1861934de 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.cpp
+++ b/llvm/lib/Target/X86/X86InstrInfo.cpp
@@ -5303,6 +5303,8 @@ bool X86InstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
case X86::CMP16ri:
case X86::CMP16ri8:
case X86::CMP8ri:
+ if (!MI.getOperand(1).isImm())
+ return false;
SrcReg = MI.getOperand(0).getReg();
SrcReg2 = 0;
CmpMask = ~0;
@@ -5334,6 +5336,8 @@ bool X86InstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
case X86::SUB16ri:
case X86::SUB16ri8:
case X86::SUB8ri:
+ if (!MI.getOperand(2).isImm())
+ return false;
SrcReg = MI.getOperand(1).getReg();
SrcReg2 = 0;
CmpMask = ~0;
diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td
index 04761380971..01185039b72 100644
--- a/llvm/lib/Target/X86/X86InstrInfo.td
+++ b/llvm/lib/Target/X86/X86InstrInfo.td
@@ -765,6 +765,12 @@ def tls64baseaddr : ComplexPattern<i64, 5, "selectTLSADDRAddr",
def vectoraddr : ComplexPattern<iPTR, 5, "selectVectorAddr", [],[SDNPWantParent]>;
+// A relocatable immediate is either an immediate operand or an operand that can
+// be relocated by the linker to an immediate, such as a regular symbol in
+// non-PIC code.
+def relocImm : ComplexPattern<iAny, 1, "selectRelocImm", [imm, X86Wrapper], [],
+ 0>;
+
//===----------------------------------------------------------------------===//
// X86 Instruction Predicate Definitions.
def TruePredicate : Predicate<"true">;
@@ -877,8 +883,6 @@ def IsNaCl : Predicate<"Subtarget->isTargetNaCl()">;
def NotNaCl : Predicate<"!Subtarget->isTargetNaCl()">;
def SmallCode : Predicate<"TM.getCodeModel() == CodeModel::Small">;
def KernelCode : Predicate<"TM.getCodeModel() == CodeModel::Kernel">;
-def FarData : Predicate<"TM.getCodeModel() != CodeModel::Small &&"
- "TM.getCodeModel() != CodeModel::Kernel">;
def NearData : Predicate<"TM.getCodeModel() == CodeModel::Small ||"
"TM.getCodeModel() == CodeModel::Kernel">;
def IsNotPIC : Predicate<"!TM.isPositionIndependent()">;
@@ -950,7 +954,7 @@ def imm8_su : PatLeaf<(i8 imm), [{
def imm16_su : PatLeaf<(i16 imm), [{
return !shouldAvoidImmediateInstFormsForSize(N);
}]>;
-def imm32_su : PatLeaf<(i32 imm), [{
+def imm32_su : PatLeaf<(i32 relocImm), [{
return !shouldAvoidImmediateInstFormsForSize(N);
}]>;
def i64immSExt32_su : PatLeaf<(i64immSExt32), [{
@@ -1380,7 +1384,7 @@ def MOV16ri : Ii16<0xB8, AddRegFrm, (outs GR16:$dst), (ins i16imm:$src),
[(set GR16:$dst, imm:$src)], IIC_MOV>, OpSize16;
def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src),
"mov{l}\t{$src, $dst|$dst, $src}",
- [(set GR32:$dst, imm:$src)], IIC_MOV>, OpSize32;
+ [(set GR32:$dst, relocImm:$src)], IIC_MOV>, OpSize32;
def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
"mov{q}\t{$src, $dst|$dst, $src}",
[(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>;
@@ -1388,7 +1392,7 @@ def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src),
let isReMaterializable = 1 in {
def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src),
"movabs{q}\t{$src, $dst|$dst, $src}",
- [(set GR64:$dst, imm:$src)], IIC_MOV>;
+ [(set GR64:$dst, relocImm:$src)], IIC_MOV>;
}
// Longer forms that use a ModR/M byte. Needed for disassembler
diff --git a/llvm/test/CodeGen/X86/compare-global.ll b/llvm/test/CodeGen/X86/compare-global.ll
new file mode 100644
index 00000000000..8e3d3a93a56
--- /dev/null
+++ b/llvm/test/CodeGen/X86/compare-global.ll
@@ -0,0 +1,22 @@
+; RUN: llc -o - %s | FileCheck %s
+
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i686-pc-windows-msvc18.0.0"
+
+@foo = external global i8
+
+define void @f(i8* %c) {
+entry:
+ ; CHECK: subl $_foo, %eax
+ %cmp = icmp eq i8* %c, @foo
+ br i1 %cmp, label %if.then, label %if.end
+
+if.then:
+ tail call void @g()
+ br label %if.end
+
+if.end:
+ ret void
+}
+
+declare void @g()
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
index c8ced6b4321..3cc7b1b4ec3 100644
--- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -805,14 +805,9 @@ static unsigned getPatternSize(const TreePatternNode *P,
if (P->isLeaf() && isa<IntInit>(P->getLeafValue()))
Size += 2;
- // FIXME: This is a hack to statically increase the priority of patterns
- // which maps a sub-dag to a complex pattern. e.g. favors LEA over ADD.
- // Later we can allow complexity / cost for each pattern to be (optionally)
- // specified. To get best possible pattern match we'll need to dynamically
- // calculate the complexity of all patterns a dag can potentially map to.
const ComplexPattern *AM = P->getComplexPatternInfo(CGP);
if (AM) {
- Size += AM->getNumOperands() * 3;
+ Size += AM->getComplexity();
// We don't want to count any children twice, so return early.
return Size;
diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp
index e87ffb730ec..42fbb986747 100644
--- a/llvm/utils/TableGen/CodeGenTarget.cpp
+++ b/llvm/utils/TableGen/CodeGenTarget.cpp
@@ -393,6 +393,16 @@ ComplexPattern::ComplexPattern(Record *R) {
SelectFunc = R->getValueAsString("SelectFunc");
RootNodes = R->getValueAsListOfDefs("RootNodes");
+ // FIXME: This is a hack to statically increase the priority of patterns which
+ // maps a sub-dag to a complex pattern. e.g. favors LEA over ADD. To get best
+ // possible pattern match we'll need to dynamically calculate the complexity
+ // of all patterns a dag can potentially map to.
+ int64_t RawComplexity = R->getValueAsInt("Complexity");
+ if (RawComplexity == -1)
+ Complexity = NumOperands * 3;
+ else
+ Complexity = RawComplexity;
+
// Parse the properties.
Properties = 0;
std::vector<Record*> PropList = R->getValueAsListOfDefs("Properties");
diff --git a/llvm/utils/TableGen/CodeGenTarget.h b/llvm/utils/TableGen/CodeGenTarget.h
index b16750c9d17..9a9522edc9b 100644
--- a/llvm/utils/TableGen/CodeGenTarget.h
+++ b/llvm/utils/TableGen/CodeGenTarget.h
@@ -196,8 +196,8 @@ class ComplexPattern {
std::string SelectFunc;
std::vector<Record*> RootNodes;
unsigned Properties; // Node properties
+ unsigned Complexity;
public:
- ComplexPattern() : NumOperands(0) {}
ComplexPattern(Record *R);
MVT::SimpleValueType getValueType() const { return Ty; }
@@ -207,6 +207,7 @@ public:
return RootNodes;
}
bool hasProperty(enum SDNP Prop) const { return Properties & (1 << Prop); }
+ unsigned getComplexity() const { return Complexity; }
};
} // End llvm namespace
OpenPOWER on IntegriCloud