Index: llvm/trunk/lib/Analysis/ValueTracking.cpp =================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp +++ llvm/trunk/lib/Analysis/ValueTracking.cpp @@ -2952,6 +2952,8 @@ BaseAlign = GV->getAlignment(); else if (const Argument *A = dyn_cast(Base)) BaseAlign = A->getParamAlignment(); + else if (auto CS = ImmutableCallSite(Base)) + BaseAlign = CS.getAttributes().getParamAlignment(AttributeSet::ReturnIndex); if (!BaseAlign) { Type *Ty = Base->getType()->getPointerElementType(); Index: llvm/trunk/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp +++ llvm/trunk/lib/AsmParser/LLParser.cpp @@ -1380,6 +1380,13 @@ B.addDereferenceableOrNullAttr(Bytes); continue; } + case lltok::kw_align: { + unsigned Alignment; + if (ParseOptionalAlignment(Alignment)) + return true; + B.addAlignmentAttr(Alignment); + continue; + } case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break; @@ -1387,7 +1394,6 @@ case lltok::kw_zeroext: B.addAttribute(Attribute::ZExt); break; // Error handling. - case lltok::kw_align: case lltok::kw_byval: case lltok::kw_inalloca: case lltok::kw_nest: Index: llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll =================================================================== --- llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll +++ llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -7,6 +7,7 @@ declare zeroext i1 @return_i1() +declare i32* @foo() @globalstr = global [6 x i8] c"hello\00" @globali32ptr = external global i32* @@ -111,6 +112,16 @@ %load21 = load i8, i8 addrspace(1)* %gep.align1.offset16, align 16 %load22 = load i8, i8 addrspace(1)* %gep.align16.offset16, align 16 +; CHECK-NOT: %no_deref_return +; CHECK: %deref_return{{.*}}(unaligned) +; CHECK: %deref_and_aligned_return{{.*}}(aligned) + %no_deref_return = call i32* @foo() + %deref_return = call dereferenceable(32) i32* @foo() + %deref_and_aligned_return = call dereferenceable(32) align 16 i32* @foo() + %load23 = load i32, i32* %no_deref_return + %load24 = load i32, i32* %deref_return, align 16 + %load25 = load i32, i32* %deref_and_aligned_return, align 16 + ret void }