[SelectionDAG] Disallow indirect "i" constraint

This allows us to delete InlineAsm::Constraint_i workarounds in
SelectionDAGISel::SelectInlineAsmMemoryOperand overrides and
TargetLowering::getInlineAsmMemConstraint overrides.

They were introduced to X86 in r237517 to prevent crashes for
constraints like "=*imr". They were later copied to other targets.
This commit is contained in:
Fangrui Song 2019-12-29 15:53:46 -08:00
parent b1fb07ddba
commit 5edb40c022
13 changed files with 8 additions and 25 deletions

View File

@ -3949,9 +3949,7 @@ public:
StringRef Constraint, MVT VT) const; StringRef Constraint, MVT VT) const;
virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const { virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const {
if (ConstraintCode == "i") if (ConstraintCode == "m")
return InlineAsm::Constraint_i;
else if (ConstraintCode == "m")
return InlineAsm::Constraint_m; return InlineAsm::Constraint_m;
return InlineAsm::Constraint_Unknown; return InlineAsm::Constraint_Unknown;
} }

View File

@ -4498,6 +4498,12 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,
TargetLowering::ConstraintType CType = TargetLowering::ConstraintType CType =
TLI.getConstraintType(OpInfo.Codes[i]); TLI.getConstraintType(OpInfo.Codes[i]);
// Indirect 'other' or 'immediate' constraints are not allowed.
if (OpInfo.isIndirect && !(CType == TargetLowering::C_Memory ||
CType == TargetLowering::C_Register ||
CType == TargetLowering::C_RegisterClass))
continue;
// If this is an 'other' or 'immediate' constraint, see if the operand is // If this is an 'other' or 'immediate' constraint, see if the operand is
// valid for it. For example, on X86 we might have an 'rI' constraint. If // valid for it. For example, on X86 we might have an 'rI' constraint. If
// the operand is an integer in the range [0..31] we want to use I (saving a // the operand is an integer in the range [0..31] we want to use I (saving a

View File

@ -304,7 +304,6 @@ bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand(
switch(ConstraintID) { switch(ConstraintID) {
default: default:
llvm_unreachable("Unexpected asm memory constraint"); llvm_unreachable("Unexpected asm memory constraint");
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m: case InlineAsm::Constraint_m:
case InlineAsm::Constraint_Q: case InlineAsm::Constraint_Q:
// We need to make sure that this one operand does not end up in XZR, thus // We need to make sure that this one operand does not end up in XZR, thus

View File

@ -5047,10 +5047,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
switch(ConstraintID) { switch(ConstraintID) {
default: default:
llvm_unreachable("Unexpected asm memory constraint"); llvm_unreachable("Unexpected asm memory constraint");
case InlineAsm::Constraint_i:
// FIXME: It seems strange that 'i' is needed here since it's supposed to
// be an immediate and not a memory constraint.
LLVM_FALLTHROUGH;
case InlineAsm::Constraint_m: case InlineAsm::Constraint_m:
case InlineAsm::Constraint_o: case InlineAsm::Constraint_o:
case InlineAsm::Constraint_Q: case InlineAsm::Constraint_Q:

View File

@ -916,7 +916,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
switch (ConstraintID) { switch (ConstraintID) {
default: default:
return true; return true;
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_o: // Offsetable. case InlineAsm::Constraint_o: // Offsetable.
case InlineAsm::Constraint_v: // Not offsetable. case InlineAsm::Constraint_v: // Not offsetable.
case InlineAsm::Constraint_m: // Memory. case InlineAsm::Constraint_m: // Memory.

View File

@ -314,7 +314,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
switch(ConstraintID) { switch(ConstraintID) {
default: default:
llvm_unreachable("Unexpected asm memory constraint"); llvm_unreachable("Unexpected asm memory constraint");
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m: case InlineAsm::Constraint_m:
case InlineAsm::Constraint_R: case InlineAsm::Constraint_R:
case InlineAsm::Constraint_ZC: case InlineAsm::Constraint_ZC:

View File

@ -1282,10 +1282,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
default: default:
llvm_unreachable("Unexpected asm memory constraint"); llvm_unreachable("Unexpected asm memory constraint");
// All memory constraints can at least accept raw pointers. // All memory constraints can at least accept raw pointers.
case InlineAsm::Constraint_i:
OutOps.push_back(Op);
OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
return false;
case InlineAsm::Constraint_m: case InlineAsm::Constraint_m:
case InlineAsm::Constraint_o: case InlineAsm::Constraint_o:
if (selectAddrRegImm16(Op, Base, Offset)) { if (selectAddrRegImm16(Op, Base, Offset)) {

View File

@ -310,7 +310,6 @@ namespace {
errs() << "ConstraintID: " << ConstraintID << "\n"; errs() << "ConstraintID: " << ConstraintID << "\n";
llvm_unreachable("Unexpected asm memory constraint"); llvm_unreachable("Unexpected asm memory constraint");
case InlineAsm::Constraint_es: case InlineAsm::Constraint_es:
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m: case InlineAsm::Constraint_m:
case InlineAsm::Constraint_o: case InlineAsm::Constraint_o:
case InlineAsm::Constraint_Q: case InlineAsm::Constraint_Q:

View File

@ -173,7 +173,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand( bool RISCVDAGToDAGISel::SelectInlineAsmMemoryOperand(
const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
switch (ConstraintID) { switch (ConstraintID) {
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m: case InlineAsm::Constraint_m:
// We just support simple memory operands that have a single address // We just support simple memory operands that have a single address
// operand and need no special handling. // operand and need no special handling.

View File

@ -380,7 +380,6 @@ SparcDAGToDAGISel::SelectInlineAsmMemoryOperand(const SDValue &Op,
SDValue Op0, Op1; SDValue Op0, Op1;
switch (ConstraintID) { switch (ConstraintID) {
default: return true; default: return true;
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_o: case InlineAsm::Constraint_o:
case InlineAsm::Constraint_m: // memory case InlineAsm::Constraint_m: // memory
if (!SelectADDRrr(Op, Op0, Op1)) if (!SelectADDRrr(Op, Op0, Op1))

View File

@ -218,7 +218,6 @@ void WebAssemblyDAGToDAGISel::Select(SDNode *Node) {
bool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand( bool WebAssemblyDAGToDAGISel::SelectInlineAsmMemoryOperand(
const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) {
switch (ConstraintID) { switch (ConstraintID) {
case InlineAsm::Constraint_i:
case InlineAsm::Constraint_m: case InlineAsm::Constraint_m:
// We just support simple memory operands that just have a single address // We just support simple memory operands that just have a single address
// operand and need no special handling. // operand and need no special handling.

View File

@ -5259,10 +5259,6 @@ SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintID,
switch (ConstraintID) { switch (ConstraintID) {
default: default:
llvm_unreachable("Unexpected asm memory constraint"); llvm_unreachable("Unexpected asm memory constraint");
case InlineAsm::Constraint_i:
// FIXME: It seems strange that 'i' is needed here since it's supposed to
// be an immediate and not a memory constraint.
LLVM_FALLTHROUGH;
case InlineAsm::Constraint_o: // offsetable ?? case InlineAsm::Constraint_o: // offsetable ??
case InlineAsm::Constraint_v: // not offsetable ?? case InlineAsm::Constraint_v: // not offsetable ??
case InlineAsm::Constraint_m: // memory case InlineAsm::Constraint_m: // memory

View File

@ -976,9 +976,7 @@ namespace llvm {
unsigned unsigned
getInlineAsmMemConstraint(StringRef ConstraintCode) const override { getInlineAsmMemConstraint(StringRef ConstraintCode) const override {
if (ConstraintCode == "i") if (ConstraintCode == "o")
return InlineAsm::Constraint_i;
else if (ConstraintCode == "o")
return InlineAsm::Constraint_o; return InlineAsm::Constraint_o;
else if (ConstraintCode == "v") else if (ConstraintCode == "v")
return InlineAsm::Constraint_v; return InlineAsm::Constraint_v;