diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index a2e436a..1663d46 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -271,32 +271,22 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
     if (!Piece.isOperand()) continue;
 
     // Look for the correct constraint index.
-    unsigned Idx = 0;
-    unsigned ConstraintIdx = 0;
-    for (unsigned i = 0, e = NS->getNumOutputs(); i != e; ++i, ++ConstraintIdx) {
-      TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i];
-      if (Idx == Piece.getOperandNo())
-        break;
-      ++Idx;
-
-      if (Info.isReadWrite()) {
-        if (Idx == Piece.getOperandNo())
-          break;
-        ++Idx;
-      }
-    }
+    unsigned ConstraintIdx = Piece.getOperandNo();
+    unsigned NumOperands = NS->getNumOutputs() + NS->getNumInputs();
 
-    for (unsigned i = 0, e = NS->getNumInputs(); i != e; ++i, ++ConstraintIdx) {
-      TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
-      if (Idx == Piece.getOperandNo())
-        break;
-      ++Idx;
+    // Look for the (ConstraintIdx - NumOperands + 1)th constraint with
+    // modifier '+'.
+    if (ConstraintIdx >= NumOperands) {
+      unsigned I = 0, E = NS->getNumOutputs();
 
-      if (Info.isReadWrite()) {
-        if (Idx == Piece.getOperandNo())
+      for (unsigned Cnt = ConstraintIdx - NumOperands; I != E; ++I)
+        if (OutputConstraintInfos[I].isReadWrite() && Cnt-- == 0) {
+          ConstraintIdx = I;
           break;
-        ++Idx;
-      }
+        }
+
+      assert(I != E && "Invalid operand number should have been caught in "
+                       " AnalyzeAsmString");
     }
 
     // Now that we have the right indexes go ahead and check.
diff --git a/test/Sema/inline-asm-validate-aarch64.c b/test/Sema/inline-asm-validate-aarch64.c
index 1364b64..2afe434 100644
--- a/test/Sema/inline-asm-validate-aarch64.c
+++ b/test/Sema/inline-asm-validate-aarch64.c
@@ -36,3 +36,19 @@ uint8_t constraint_r_symbolic_macro(uint8_t *addr) {
 
   return byte;
 }
+
+// CHECK: warning: value size does not match register size specified by the constraint and modifier
+// CHECK: asm ("%w0 %w1 %2" : "+r" (one) : "r" (wide_two));
+// CHECK: note: use constraint modifier "w"
+// CHECK: fix-it:{{.*}}:{47:17-47:19}:"%w2"
+
+void read_write_modifier0(int one, int two) {
+  long wide_two = two;
+  asm ("%w0 %w1 %2" : "+r" (one) : "r" (wide_two));
+}
+
+// No warnings expected.
+void read_write_modifier1(int one, int two) {
+  long wide_two = two;
+  asm ("%w0 %1" : "+r" (one), "+r" (wide_two));
+}
