aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-27 00:47:27 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-27 00:47:27 +0000
commitd8e10d26b5a24257fe13c289b653fd450326eeff (patch)
treee4324396380cbfd6ef524dd2226886b2b10b22b5
parent524c308506e77e173092e87a0724a27817311428 (diff)
When mapping restrict to noalias, look for 'restrict' on the parameter variable
instead of the canonical parameter type (which has correctly dropped all such direct qualifiers). Fixes PR6695. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99688 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGCall.cpp8
-rw-r--r--test/CodeGen/restrict.c26
2 files changed, 32 insertions, 2 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 072b1f6585..dcd0beab10 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -623,8 +623,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
const ABIArgInfo &AI = it->info;
unsigned Attributes = 0;
- if (ParamType.isRestrictQualified())
- Attributes |= llvm::Attribute::NoAlias;
+ // 'restrict' -> 'noalias' is done in EmitFunctionProlog when we
+ // have the corresponding parameter variable. It doesn't make
+ // sense to do it here because parameters are so fucked up.
switch (AI.getKind()) {
case ABIArgInfo::Coerce:
@@ -749,6 +750,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
V = CreateMemTemp(Ty);
Builder.CreateStore(AI, V);
} else {
+ if (Arg->getType().isRestrictQualified())
+ AI->addAttr(llvm::Attribute::NoAlias);
+
if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
// This must be a promotion, for something like
// "void a(x) short x; {..."
diff --git a/test/CodeGen/restrict.c b/test/CodeGen/restrict.c
new file mode 100644
index 0000000000..8bbff24ace
--- /dev/null
+++ b/test/CodeGen/restrict.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-darwin-apple -emit-llvm %s -o - | FileCheck %s
+
+// PR6695
+
+// CHECK: define void @test0(i32* %{{.*}}, i32 %{{.*}})
+void test0(int *x, int y) {
+}
+
+// CHECK: define void @test1(i32* noalias %{{.*}}, i32 %{{.*}})
+void test1(int * restrict x, int y) {
+}
+
+// CHECK: define void @test2(i32* %{{.*}}, i32* noalias %{{.*}})
+void test2(int *x, int * restrict y) {
+}
+
+typedef int * restrict rp;
+
+// CHECK: define void @test3(i32* noalias %{{.*}}, i32 %{{.*}})
+void test3(rp x, int y) {
+}
+
+// CHECK: define void @test4(i32* %{{.*}}, i32* noalias %{{.*}})
+void test4(int *x, rp y) {
+}
+