]> granicus.if.org Git - clang/commitdiff
When mapping restrict to noalias, look for 'restrict' on the parameter variable
authorJohn McCall <rjmccall@apple.com>
Sat, 27 Mar 2010 00:47:27 +0000 (00:47 +0000)
committerJohn McCall <rjmccall@apple.com>
Sat, 27 Mar 2010 00:47:27 +0000 (00:47 +0000)
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

lib/CodeGen/CGCall.cpp
test/CodeGen/restrict.c [new file with mode: 0644]

index 072b1f6585fdaba89223cb5f9b9a41b385c001ba..dcd0beab10fe7bf112f905a9b8d56da1bcaf42a1 100644 (file)
@@ -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 (file)
index 0000000..8bbff24
--- /dev/null
@@ -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) {
+}
+