diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2483,6 +2483,22 @@ } } + if (isa(&S)) { + if (Clobber == "eax" || Clobber == "edx") { + if (Constraints.find("=&A") != std::string::npos) + continue; + std::string::size_type position1 = Constraints.find("={eax}"); + if (position1 != std::string::npos) { + Constraints.insert(position1 + 1, "&"); + continue; + } + std::string::size_type position2 = Constraints.find("=A"); + if (position2 != std::string::npos) { + Constraints.insert(position2 + 1, "&"); + continue; + } + } + } if (!Constraints.empty()) Constraints += ','; diff --git a/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c --- a/clang/test/CodeGen/ms-inline-asm.c +++ b/clang/test/CodeGen/ms-inline-asm.c @@ -114,7 +114,7 @@ // CHECK: call i32 asm sideeffect inteldialect // CHECK-SAME: mov eax, $2 // CHECK-SAME: mov $0, eax -// CHECK-SAME: "=*m,={eax},*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) +// CHECK-SAME: "=*m,=&{eax},*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}) // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32, i32* [[J]], align 4 // CHECK: ret i32 [[RET]] } @@ -140,7 +140,7 @@ // CHECK-SAME: mov $0, eax // CHECK-SAME: mov eax, $4 // CHECK-SAME: mov $1, eax -// CHECK-SAME: "=*m,=*m,={eax},*m,*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) +// CHECK-SAME: "=*m,=*m,=&{eax},*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}, i32* %{{.*}}) } void t13() { diff --git a/clang/test/CodeGenCXX/ms-inline-asm-return.cpp b/clang/test/CodeGenCXX/ms-inline-asm-return.cpp --- a/clang/test/CodeGenCXX/ms-inline-asm-return.cpp +++ b/clang/test/CodeGenCXX/ms-inline-asm-return.cpp @@ -13,7 +13,17 @@ } } // CHECK-LABEL: define dso_local i64 @f_i64() -// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "=A,~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "=&A,{{.*}}" +// CHECK: ret i64 %[[r]] + +long long f_i64_reverse() { + __asm { + mov edx, 1 + mov eax, 1 + } +} +// CHECK-LABEL: define dso_local i64 @f_i64_reverse() +// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov edx, $$1\0A\09mov eax, $$1", "=&A,{{.*}}" // CHECK: ret i64 %[[r]] int f_i32() { @@ -23,7 +33,17 @@ } } // CHECK-LABEL: define dso_local i32 @f_i32() -// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "=&{eax},~{edx},{{.*}}" +// CHECK: ret i32 %[[r]] + +int f_i32_reverse() { + __asm { + mov edx, 1 + mov eax, 1 + } +} +// CHECK-LABEL: define dso_local i32 @f_i32_reverse() +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov edx, $$1\0A\09mov eax, $$1", "=&{eax},~{edx},{{.*}}" // CHECK: ret i32 %[[r]] short f_i16() { @@ -33,7 +53,7 @@ } } // CHECK-LABEL: define dso_local signext i16 @f_i16() -// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "=&{eax},~{edx},{{.*}}" // CHECK: %[[r_i16:[^ ]*]] = trunc i32 %[[r]] to i16 // CHECK: ret i16 %[[r_i16]] @@ -44,7 +64,7 @@ } } // CHECK-LABEL: define dso_local signext i8 @f_i8() -// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "=&{eax},~{edx},{{.*}}" // CHECK: %[[r_i8:[^ ]*]] = trunc i32 %[[r]] to i8 // CHECK: ret i8 %[[r_i8]] @@ -55,7 +75,7 @@ } } // CHECK-LABEL: define dso_local zeroext i1 @f_i1() -// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "=&{eax},~{edx},{{.*}}" // CHECK: %[[r_i8:[^ ]*]] = trunc i32 %[[r]] to i8 // CHECK: store i8 %[[r_i8]], i8* %{{.*}} // CHECK: %[[r_i1:[^ ]*]] = load i1, i1* %{{.*}} @@ -70,7 +90,7 @@ } } // CHECK-LABEL: define dso_local i32 @f_s4() -// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$16843009", "={eax},~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$16843009", "=&{eax},{{.*}}" // CHECK: store i32 %[[r]], i32* %{{.*}} // CHECK: %[[r_i32:[^ ]*]] = load i32, i32* %{{.*}} // CHECK: ret i32 %[[r_i32]] @@ -85,7 +105,7 @@ } } // CHECK-LABEL: define dso_local i64 @f_s8() -// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$16843009\0A\09mov edx, $$85", "=A,~{eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$16843009\0A\09mov edx, $$85", "=&A,{{.*}}" // CHECK: store i64 %[[r]], i64* %{{.*}} // CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}} // CHECK: ret i64 %[[r_i64]] @@ -96,5 +116,5 @@ __asm xor eax, eax } // CHECK-LABEL: define dso_local i32 @main() -// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "xor eax, eax", "={eax},{{.*}}" +// CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "xor eax, eax", "=&{eax},{{.*}}" // CHECK: ret i32 %[[r]]