diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index f4cced8..19b2ad4 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -2548,9 +2548,10 @@ public:
   /// AsmOperandInfo, setting OpInfo.ConstraintCode and OpInfo.ConstraintType.
   /// If the actual operand being passed in is available, it can be passed in as
   /// Op, otherwise an empty SDValue can be passed.
-  virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
-                                      SDValue Op,
-                                      SelectionDAG *DAG = nullptr) const;
+  virtual void
+  ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op,
+                         SelectionDAG *DAG = nullptr,
+                         const ImmutableCallSite *CS = nullptr) const;
 
   /// Given a constraint, return the type of constraint it is for this target.
   virtual ConstraintType getConstraintType(const std::string &Constraint) const;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 51af1ca..bbd4973 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -6411,7 +6411,7 @@ void SelectionDAGBuilder::visitInlineAsm(ImmutableCallSite CS) {
     }
 
     // Compute the constraint code and ConstraintType to use.
-    TLI->ComputeConstraintToUse(OpInfo, OpInfo.CallOperand, &DAG);
+    TLI->ComputeConstraintToUse(OpInfo, OpInfo.CallOperand, &DAG, &CS);
 
     if (OpInfo.ConstraintType == TargetLowering::C_Memory &&
         OpInfo.Type == InlineAsm::isClobber)
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 1bd3d29..e444bbe 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -2581,9 +2581,10 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,
 /// ComputeConstraintToUse - Determines the constraint code and constraint
 /// type to use for the specific AsmOperandInfo, setting
 /// OpInfo.ConstraintCode and OpInfo.ConstraintType.
-void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,
-                                            SDValue Op,
-                                            SelectionDAG *DAG) const {
+void
+TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,SDValue Op,
+                                       SelectionDAG *DAG,
+                                       const ImmutableCallSite *CS) const {
   assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
 
   // Single-letter constraints ('r') are very common.
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 66c00fb..761fb8e 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -23034,6 +23034,36 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
   return false;
 }
 
+void
+X86TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,
+                                          SDValue Op, SelectionDAG *DAG,
+                                          const ImmutableCallSite *CS) const {
+  TargetLowering::ComputeConstraintToUse(OpInfo, Op, DAG, CS);
+
+  if (!CS || !DAG)
+    return;
+
+  if (!Subtarget->is32Bit() || !OpInfo.ConstraintVT.isInteger() ||
+      OpInfo.ConstraintVT.getSizeInBits() <= 32)
+    return;
+
+  bool Error = StringSwitch<bool>(OpInfo.ConstraintCode)
+                   .Case("{ax}", true)
+                   .Case("{bx}", true)
+                   .Case("{cx}", true)
+                   .Case("{dx}", true)
+                   .Case("{si}", true)
+                   .Case("{di}", true)
+                   .Default(false);
+
+  if (Error) {
+      DAG->getContext()->emitError(CS->getInstruction(),
+                                   "Cannot bind a variable larger than 32-bit "
+                                   "to a single register in 32-bit mode");
+      exit(1);
+  }
+}
+
 /// getConstraintType - Given a constraint letter, return the type of
 /// constraint it is for this target.
 X86TargetLowering::ConstraintType
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 90d7836..e23dedd 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -643,6 +643,12 @@ namespace llvm {
 
     bool ExpandInlineAsm(CallInst *CI) const override;
 
+    void
+    ComputeConstraintToUse(AsmOperandInfo &OpInfo, SDValue Op,
+                           SelectionDAG *DAG = nullptr,
+                           const ImmutableCallSite *CS = nullptr
+                          ) const override;
+
     ConstraintType
       getConstraintType(const std::string &Constraint) const override;
 
diff --git a/test/CodeGen/X86/inline-asm-regsize.ll b/test/CodeGen/X86/inline-asm-regsize.ll
new file mode 100644
index 0000000..3b38bc9
--- /dev/null
+++ b/test/CodeGen/X86/inline-asm-regsize.ll
@@ -0,0 +1,13 @@
+; RUN: not llc  -mcpu=generic -mtriple=i386-apple-darwin -no-integrated-as < %s  2> %t
+; RUN: FileCheck --check-prefix=CHECK-ERRORS < %t %s
+
+; CHECK-ERRORS: Cannot bind a variable larger than 32-bit to a single register in 32-bit mode
+
+define i64 @test_a() {
+entry:
+  %r = alloca i64, align 8
+  %0 = call i64 asm "foo2 $0", "={ax},~{dirflag},~{fpsr},~{flags}"()
+  store i64 %0, i64* %r, align 8
+  %1 = load i64* %r, align 8
+  ret i64 %1
+}
