Handle 'X' constraint in asm's better.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46485 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp
index 7c4a8e1..2b83588 100644
--- a/lib/CodeGen/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter.cpp
@@ -1108,9 +1108,10 @@
// Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
- // If this asmstr is empty, don't bother printing the #APP/#NOAPP markers.
+ // If this asmstr is empty, just print the #APP/#NOAPP markers.
+ // These are useful to see where empty asm's wound up.
if (AsmStr[0] == 0) {
- O << "\n"; // Tab already printed, avoid double indenting next instr.
+ O << TAI->getInlineAsmStart() << "\n\t" << TAI->getInlineAsmEnd() << "\n";
return;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 4b88f78..406011a 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3250,27 +3250,41 @@
if (Codes.size() == 1) { // Single-letter constraints ('r') are very common.
ConstraintCode = *Current;
ConstraintType = CurType;
- return;
+ } else {
+ unsigned CurGenerality = getConstraintGenerality(CurType);
+
+ // If we have multiple constraints, try to pick the most general one ahead
+ // of time. This isn't a wonderful solution, but handles common cases.
+ for (unsigned j = 1, e = Codes.size(); j != e; ++j) {
+ TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]);
+ unsigned ThisGenerality = getConstraintGenerality(ThisType);
+ if (ThisGenerality > CurGenerality) {
+ // This constraint letter is more general than the previous one,
+ // use it.
+ CurType = ThisType;
+ Current = &Codes[j];
+ CurGenerality = ThisGenerality;
+ }
+ }
+
+ ConstraintCode = *Current;
+ ConstraintType = CurType;
}
-
- unsigned CurGenerality = getConstraintGenerality(CurType);
-
- // If we have multiple constraints, try to pick the most general one ahead
- // of time. This isn't a wonderful solution, but handles common cases.
- for (unsigned j = 1, e = Codes.size(); j != e; ++j) {
- TargetLowering::ConstraintType ThisType = TLI.getConstraintType(Codes[j]);
- unsigned ThisGenerality = getConstraintGenerality(ThisType);
- if (ThisGenerality > CurGenerality) {
- // This constraint letter is more general than the previous one,
- // use it.
- CurType = ThisType;
- Current = &Codes[j];
- CurGenerality = ThisGenerality;
+
+ if (ConstraintCode == "X") {
+ if (isa<BasicBlock>(CallOperandVal) || isa<ConstantInt>(CallOperandVal))
+ return;
+ // This matches anything. Labels and constants we handle elsewhere
+ // ('X' is the only thing that matches labels). Otherwise, try to
+ // resolve it to something we know about by looking at the actual
+ // operand type.
+ std::string s = "";
+ TLI.lowerXConstraint(ConstraintVT, s);
+ if (s!="") {
+ ConstraintCode = s;
+ ConstraintType = TLI.getConstraintType(ConstraintCode);
}
}
-
- ConstraintCode = *Current;
- ConstraintType = CurType;
}
@@ -3492,7 +3506,8 @@
if (OpInfo.CallOperandVal) {
if (isa<BasicBlock>(OpInfo.CallOperandVal))
OpInfo.CallOperand =
- DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(OpInfo.CallOperandVal)]);
+ DAG.getBasicBlock(FuncInfo.MBBMap[cast<BasicBlock>(
+ OpInfo.CallOperandVal)]);
else {
OpInfo.CallOperand = getValue(OpInfo.CallOperandVal);
const Type *OpTy = OpInfo.CallOperandVal->getType();
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 3ccfcfa..bd0392e 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -1525,6 +1525,19 @@
return C_Unknown;
}
+/// LowerXConstraint - try to replace an X constraint, which matches anything,
+/// with another that has more specific requirements based on the type of the
+/// corresponding operand.
+void TargetLowering::lowerXConstraint(MVT::ValueType ConstraintVT,
+ std::string& s) const {
+ if (MVT::isInteger(ConstraintVT))
+ s = "r";
+ else if (MVT::isFloatingPoint(ConstraintVT))
+ s = "f"; // works for many targets
+ else
+ s = "";
+}
+
/// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
/// vector. If it is invalid, don't add anything to Ops.
void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,