summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Parse/ParseStmtAsm.cpp9
-rw-r--r--clang/test/CodeGen/ms-inline-asm.c8
2 files changed, 13 insertions, 4 deletions
diff --git a/clang/lib/Parse/ParseStmtAsm.cpp b/clang/lib/Parse/ParseStmtAsm.cpp
index 59e96d982a0..85cd22fef42 100644
--- a/clang/lib/Parse/ParseStmtAsm.cpp
+++ b/clang/lib/Parse/ParseStmtAsm.cpp
@@ -621,10 +621,11 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
MII.get(), IP.get(), Callback))
return StmtError();
- // Filter out "fpsw". Clang doesn't accept it, and it always lists flags and
- // fpsr as clobbers.
- auto End = std::remove(Clobbers.begin(), Clobbers.end(), "fpsw");
- Clobbers.erase(End, Clobbers.end());
+ // Filter out "fpsw" and "mxcsr". They aren't valid GCC asm clobber
+ // constraints. Clang always adds fpsr to the clobber list anyway.
+ llvm::erase_if(Clobbers, [](const std::string &C) {
+ return C == "fpsw" || C == "mxcsr";
+ });
// Build the vector of clobber StringRefs.
ClobberRefs.insert(ClobberRefs.end(), Clobbers.begin(), Clobbers.end());
diff --git a/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c
index 6db0cff50d0..69b732c9acc 100644
--- a/clang/test/CodeGen/ms-inline-asm.c
+++ b/clang/test/CodeGen/ms-inline-asm.c
@@ -649,6 +649,14 @@ void label6(){
// CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.${:uid}__label\0A\09{{.*}}__MSASMLABEL_.${:uid}__label:", "~{dirflag},~{fpsr},~{flags}"()
}
+// Don't include mxcsr in the clobber list.
+void mxcsr() {
+ char buf[4096];
+ __asm fxrstor buf
+}
+// CHECK-LABEL: define void @mxcsr
+// CHECK: call void asm sideeffect inteldialect "fxrstor byte ptr $0", "=*m,~{dirflag},~{fpsr},~{flags}"
+
typedef union _LARGE_INTEGER {
struct {
unsigned int LowPart;
OpenPOWER on IntegriCloud