diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 424997d125e4..9be734062698 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1515,8 +1515,10 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, else if (Feature.startswith("tune=")) // We don't support cpu tuning this way currently. ; - else - Features.push_back("+" + Feature.str()); + else if (Feature.startswith("mno-")) + Features.push_back("-" + Feature.split("-").second.str()); + else + Features.push_back("+" + Feature.str()); } } } diff --git a/clang/test/CodeGen/attr-target.c b/clang/test/CodeGen/attr-target.c index 2e548cc701a0..e21f047ed0ad 100644 --- a/clang/test/CodeGen/attr-target.c +++ b/clang/test/CodeGen/attr-target.c @@ -6,6 +6,8 @@ int __attribute__((target("avx,sse4.2,arch=ivybridge"))) foo(int a) { return 4; int __attribute__((target("tune=sandybridge"))) walrus(int a) { return 4; } +int __attribute__((target("mno-sse2"))) echidna(int a) { return 4; } + int bar(int a) { return baz(a) + foo(a); } // Check that we emit the additional subtarget and cpu features for foo and not for baz or bar. @@ -13,6 +15,8 @@ int bar(int a) { return baz(a) + foo(a); } // CHECK: foo{{.*}} #1 // We ignore the tune attribute so walrus should be identical to baz and bar. // CHECK: walrus{{.*}} #0 +// CHECK: echidna{{.*}} #2 // CHECK: bar{{.*}} #0 // CHECK: #0 = {{.*}}"target-cpu"="x86-64" "target-features"="+sse,+sse2" // CHECK: #1 = {{.*}}"target-cpu"="ivybridge" "target-features"="+sse,+sse2,+avx,+sse4.2" +// CHECK: #2 = {{.*}}"target-cpu"="x86-64" "target-features"="+sse,+sse2,-sse2"