diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/docs/LangRef.rst | 7 | ||||
| -rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 8 | ||||
| -rw-r--r-- | llvm/test/Bitcode/attributes.ll | 5 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/align-attr.ll | 15 |
4 files changed, 29 insertions, 6 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 867ef741da1..34873e1f41d 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -921,6 +921,13 @@ Currently, only the following parameter attributes are defined: the first parameter. This is not a valid attribute for return values. +``align <n>`` + This indicates that the pointer value may be assumed by the optimizer to + have the specified alignment. + + Note that this attribute has additional semantics when combined with the + ``byval`` attribute. + .. _noalias: ``noalias`` diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e6d09f4e31f..4edfb615f2a 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -308,13 +308,9 @@ void llvm::computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne, } if (Argument *A = dyn_cast<Argument>(V)) { - unsigned Align = 0; + unsigned Align = A->getType()->isPointerTy() ? A->getParamAlignment() : 0; - if (A->hasByValOrInAllocaAttr()) { - // Get alignment information off byval/inalloca arguments if specified in - // the IR. - Align = A->getParamAlignment(); - } else if (TD && A->hasStructRetAttr()) { + if (!Align && TD && A->hasStructRetAttr()) { // An sret parameter has at least the ABI alignment of the return type. Type *EltTy = cast<PointerType>(A->getType())->getElementType(); if (EltTy->isSized()) diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll index 2490e592072..9a429f6e21f 100644 --- a/llvm/test/Bitcode/attributes.ll +++ b/llvm/test/Bitcode/attributes.ll @@ -239,6 +239,11 @@ define dereferenceable(18446744073709551606) i8* @f40(i8* dereferenceable(184467 ret i8* %a } +define void @f41(i8* align 32, double* align 64) { +; CHECK: define void @f41(i8* align 32, double* align 64) { + ret void +} + ; CHECK: attributes #0 = { noreturn } ; CHECK: attributes #1 = { nounwind } ; CHECK: attributes #2 = { readnone } diff --git a/llvm/test/Transforms/InstCombine/align-attr.ll b/llvm/test/Transforms/InstCombine/align-attr.ll new file mode 100644 index 00000000000..9f366bf8fab --- /dev/null +++ b/llvm/test/Transforms/InstCombine/align-attr.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: nounwind uwtable +define i32 @foo1(i32* align 32 %a) #0 { +entry: + %0 = load i32* %a, align 4 + ret i32 %0 + +; CHECK-LABEL: @foo1 +; CHECK-DAG: load i32* %a, align 32 +; CHECK: ret i32 +} + |

