diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8e9d38f..bf12f8b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -14067,6 +14067,8 @@ get_some_local_dynamic_name (void)
    ~ -- print "i" if TARGET_AVX2, "f" otherwise.
    @ -- print a segment register of thread base pointer load
    ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
+   { -- print an opening curly brace
+   } -- print a closing curly brace
  */
 
 void
@@ -14557,6 +14559,11 @@ ix86_print_operand (FILE *file, rtx x, int code)
 	    fputs ("addr32 ", file);
 	  return;
 
+        case '{':
+        case '}':
+          putc (code, file);
+          return;
+
 	default:
 	    output_operand_lossage ("invalid operand code '%c'", code);
 	}
@@ -14698,7 +14705,8 @@ static bool
 ix86_print_operand_punct_valid_p (unsigned char code)
 {
   return (code == '@' || code == '*' || code == '+' || code == '&'
-	  || code == ';' || code == '~' || code == '^');
+	  || code == ';' || code == '~' || code == '^' || code == '{'
+	  || code == '}');
 }
 
 /* Print a memory operand whose address is ADDR.  */
diff --git a/gcc/final.c b/gcc/final.c
index 714137c..d7bdf65 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -3431,8 +3431,21 @@ do_assembler_dialects (const char *p, int *dialect)
            DIALECT_NUMBER of strings ending with '|'.  */
         for (i = 0; i < dialect_number; i++)
           {
-            while (*p && *p != '}' && *p++ != '|')
-	      ;
+            while (*p && *p != '}')
+	      {
+		if (*p == '|')
+		  {
+		    p++;
+		    break;
+		  }
+
+		/* Skip over any character after a percent sign.  */
+		if (*p == '%')
+		  p++;
+		if (*p)
+		  p++;
+	      }
+
             if (*p == '}')
 	      break;
           }
@@ -3453,8 +3466,19 @@ do_assembler_dialects (const char *p, int *dialect)
 		  output_operand_lossage ("unterminated assembly dialect alternative");
 		  break;
 		}
+
+	      /* Skip over any character after a percent sign.  */
+	      if (*p == '%' && *(p + 1))
+		{
+		  p += 2;
+		  continue;
+		}
+
+	      if (*p++ == '}')
+		break;
             }
-          while (*p++ != '}');
+          while (1);
+
           *dialect = 0;
         }
       else
diff --git a/gcc/testsuite/gcc.target/i386/asm-dialect-2.c b/gcc/testsuite/gcc.target/i386/asm-dialect-2.c
new file mode 100644
index 0000000..321166a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/asm-dialect-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-masm=att" } */
+
+int a, b;
+
+void f()
+{
+  /* Check for escaped curly braces support.  */
+  asm volatile ("{%%%{a%}|%%%}b}" : :);
+  asm volatile ("{att|intel}" : :);
+  a += b;
+}
+/* { dg-final { scan-assembler "%{a}" } } */
