Support align attribute for return values
authorArtur Pilipenko <apilipenko@azulsystems.com>
Fri, 18 Sep 2015 12:33:31 +0000 (12:33 +0000)
committerArtur Pilipenko <apilipenko@azulsystems.com>
Fri, 18 Sep 2015 12:33:31 +0000 (12:33 +0000)
Reviewed By: reames

Differential Revision: http://reviews.llvm.org/D12844

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247984 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ValueTracking.cpp
lib/AsmParser/LLParser.cpp
test/Analysis/ValueTracking/memory-dereferenceable.ll

index ff20a0f2b42a6c586414c54caa5a9fc0d8f1fc2a..98fbfdc861c6dde266c941dfb07d4003b45b168d 100644 (file)
@@ -2952,6 +2952,8 @@ static bool isAligned(const Value *Base, APInt Offset, unsigned Align,
     BaseAlign = GV->getAlignment();
   else if (const Argument *A = dyn_cast<Argument>(Base))
     BaseAlign = A->getParamAlignment();
     BaseAlign = GV->getAlignment();
   else if (const Argument *A = dyn_cast<Argument>(Base))
     BaseAlign = A->getParamAlignment();
+  else if (auto CS = ImmutableCallSite(Base))
+    BaseAlign = CS.getAttributes().getParamAlignment(AttributeSet::ReturnIndex);
 
   if (!BaseAlign) {
     Type *Ty = Base->getType()->getPointerElementType();
 
   if (!BaseAlign) {
     Type *Ty = Base->getType()->getPointerElementType();
index b2f7af6174326ad58fd947534f5ded103cdf34f0..d7a05fe99c8cb69fd4c8876f20d02d46b39f7f28 100644 (file)
@@ -1380,6 +1380,13 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
       B.addDereferenceableOrNullAttr(Bytes);
       continue;
     }
       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;
     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 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
     case lltok::kw_zeroext:         B.addAttribute(Attribute::ZExt); break;
 
     // Error handling.
     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:
     case lltok::kw_byval:
     case lltok::kw_inalloca:
     case lltok::kw_nest:
index 1d6f32eea72de09e73392651035a3ed2145b5473..550b01c4c9aa12e2f38690dcabe85c91f26cdfe0 100644 (file)
@@ -7,6 +7,7 @@ target datalayout = "e"
 
 declare zeroext i1 @return_i1()
 
 
 declare zeroext i1 @return_i1()
 
+declare i32* @foo()
 @globalstr = global [6 x i8] c"hello\00"
 @globali32ptr = external global i32*
 
 @globalstr = global [6 x i8] c"hello\00"
 @globali32ptr = external global i32*
 
@@ -111,6 +112,16 @@ entry:
     %load21 = load i8, i8 addrspace(1)* %gep.align1.offset16, align 16
     %load22 = load i8, i8 addrspace(1)* %gep.align16.offset16, align 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
 }
 
     ret void
 }