summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/docs/LangRef.rst7
-rw-r--r--llvm/lib/Analysis/ValueTracking.cpp8
-rw-r--r--llvm/test/Bitcode/attributes.ll5
-rw-r--r--llvm/test/Transforms/InstCombine/align-attr.ll15
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
+}
+
OpenPOWER on IntegriCloud