From: Reid Kleckner Date: Tue, 14 Feb 2017 21:38:17 +0000 (+0000) Subject: MS inline asm: Filter MXCSR out of the inferred clobber list X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d418b54ac44ba3ed94302aaf3ac1e26de8b078c2;p=clang MS inline asm: Filter MXCSR out of the inferred clobber list Since r295004, LLVM has started modelling this new register, but we don't have GCC constraint inline asm spellings for it yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@295107 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp index 59e96d982a..85cd22fef4 100644 --- a/lib/Parse/ParseStmtAsm.cpp +++ b/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/test/CodeGen/ms-inline-asm.c b/test/CodeGen/ms-inline-asm.c index 6db0cff50d..69b732c9ac 100644 --- a/test/CodeGen/ms-inline-asm.c +++ b/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;