diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index 580f7e5d9e4..ffe7411b778 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -18,6 +18,7 @@ #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" +#include "llvm/ParameterAttributes.h" #include "llvm/GlobalVariable.h" #include "llvm/Instructions.h" #include "llvm/Pass.h" @@ -294,6 +295,21 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, // Pointing at a discernible object? if (O1) { + // Check for noalias attribute + if (isa(O1)) { + const Argument *Arg = cast(O1); + const Function *Func = Arg->getParent(); + const ParamAttrsList *Attr = Func->getFunctionType()->getParamAttrs(); + if (Attr) { + unsigned Idx = 1; + for (Function::const_arg_iterator I = Func->arg_begin(), + E = Func->arg_end(); I != E; ++I, ++Idx) { + if (&(*I) == Arg && + Attr->paramHasAttr(Idx, ParamAttr::NoAlias)) + return NoAlias; + } + } + } if (O2) { if (isa(O1)) { // Incoming argument cannot alias locally allocated object! @@ -307,7 +323,22 @@ BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size, // If they are two different objects, we know that we have no alias... return NoAlias; } - + + // Check for noalias atrribute independently from above logic + if (isa(O2)) { + const Argument *Arg = cast(O2); + const Function *Func = Arg->getParent(); + const ParamAttrsList *Attr = Func->getFunctionType()->getParamAttrs(); + if (Attr) { + unsigned Idx = 1; + for (Function::const_arg_iterator I = Func->arg_begin(), + E = Func->arg_end(); I != E; ++I, ++Idx) { + if (&(*I) == Arg && + Attr->paramHasAttr(Idx, ParamAttr::NoAlias)) + return NoAlias; + } + } + } // If they are the same object, they we can look at the indexes. If they // index off of the object is the same for both pointers, they must alias. // If they are provably different, they must not alias. Otherwise, we diff --git a/test/Analysis/BasicAA/2007-07-31-NoAliasTest.ll b/test/Analysis/BasicAA/2007-07-31-NoAliasTest.ll new file mode 100644 index 00000000000..f760de35cdc --- /dev/null +++ b/test/Analysis/BasicAA/2007-07-31-NoAliasTest.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as %s -o - | opt -aa-eval -print-may-aliases -disable-output |& grep '1 may alias' +; RUN: llvm-as %s -o - | opt -aa-eval -print-may-aliases -disable-output |& grep '5 no alias' +; RUN: llvm-as %s -o - | opt -aa-eval -print-may-aliases -disable-output |& grep 'MayAlias: i32* %ptr4, i32* %ptr2' + +define void @_Z3fooPiS_RiS_(i32* noalias %ptr1, i32* %ptr2, i32* noalias %ptr3, i32* %ptr4) { +entry: + store i32 0, i32* %ptr1 + store i32 0, i32* %ptr2 + store i32 0, i32* %ptr3 + store i32 0, i32* %ptr4 + ret void +} \ No newline at end of file