[llvm] a6492e2 - [IR] Value::getPointerAlignment(): handle pointer constants

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 21 14:33:14 PST 2020


Author: Roman Lebedev
Date: 2020-01-22T01:32:46+03:00
New Revision: a6492e22711e45f1e60416371f7b5c29be5f508e

URL: https://github.com/llvm/llvm-project/commit/a6492e22711e45f1e60416371f7b5c29be5f508e
DIFF: https://github.com/llvm/llvm-project/commit/a6492e22711e45f1e60416371f7b5c29be5f508e.diff

LOG: [IR] Value::getPointerAlignment(): handle pointer constants

Summary:
New `@test13` in `Attributor/align.ll` is the main motivation - `null` pointer
really does not limit our alignment knowledge, in fact it is fully aligned
since it has no bits set.

Here we don't special-case `null` pointer because it is somewhat controversial
to add one more place where we enforce that `null` pointer is zero,
but instead we do the more general thing of trying to perform constant-fold
of pointer constant to an integer, and perform alignment inferrment on that.

Reviewers: jdoerfert, gchatelet, courbet, sstefan1

Reviewed By: jdoerfert

Subscribers: hiraditya, arphaman, jfb, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D73131

Added: 
    

Modified: 
    llvm/lib/IR/Value.cpp
    llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
    llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
    llvm/test/Transforms/Attributor/align.ll
    llvm/test/Transforms/Attributor/callbacks.ll
    llvm/test/Transforms/Attributor/nocapture-1.ll
    llvm/test/Transforms/Attributor/nonnull.ll
    llvm/test/Transforms/Attributor/value-simplify.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index cf9d08f6fc02..8e2d49fbb9c8 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -729,6 +729,17 @@ MaybeAlign Value::getPointerAlignment(const DataLayout &DL) const {
       ConstantInt *CI = mdconst::extract<ConstantInt>(MD->getOperand(0));
       return MaybeAlign(CI->getLimitedValue());
     }
+  } else if (auto *CstPtr = dyn_cast<Constant>(this)) {
+    if (auto *CstInt = dyn_cast_or_null<ConstantInt>(ConstantExpr::getPtrToInt(
+            const_cast<Constant *>(CstPtr), DL.getIntPtrType(getType()),
+            /*OnlyIfReduced=*/true))) {
+      size_t TrailingZeros = CstInt->getValue().countTrailingZeros();
+      // While the actual alignment may be large, elsewhere we have
+      // an arbitrary upper alignmet limit, so let's clamp to it.
+      return Align(TrailingZeros < Value::MaxAlignmentExponent
+                       ? uint64_t(1) << TrailingZeros
+                       : Value::MaximumAlignment);
+    }
   }
   return llvm::None;
 }

diff  --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
index bde1ce855dee..8742c4fa46a0 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
@@ -6,9 +6,9 @@
 ; because there is a load of %A in the entry block
 define internal i32 @callee(i1 %C, i32* %A) {
 ; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nocapture nofree nonnull readonly dereferenceable(4) [[A:%.*]])
+; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nocapture nofree nonnull readonly align 536870912 dereferenceable(4) [[A:%.*]])
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A_0:%.*]] = load i32, i32* null
+; CHECK-NEXT:    [[A_0:%.*]] = load i32, i32* null, align 536870912
 ; CHECK-NEXT:    br label [[F:%.*]]
 ; CHECK:       T:
 ; CHECK-NEXT:    unreachable
@@ -34,7 +34,7 @@ F:
 
 define i32 @foo() {
 ; CHECK-LABEL: define {{[^@]+}}@foo()
-; CHECK-NEXT:    [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nofree readonly null)
+; CHECK-NEXT:    [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nofree readonly align 536870912 null)
 ; CHECK-NEXT:    ret i32 [[X]]
 ;
   %X = call i32 @callee(i1 false, i32* null)             ; <i32> [#uses=1]

diff  --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
index b6b5e19680d7..2aa6e61eea78 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
@@ -33,10 +33,10 @@ define dso_local i32 @main() {
 ; CHECK-NEXT:    [[ALLOC1:%.*]] = alloca i8, align 8
 ; CHECK-NEXT:    [[ALLOC2:%.*]] = alloca i8, align 8
 ; CHECK-NEXT:    [[THREAD:%.*]] = alloca i64, align 8
-; CHECK-NEXT:    [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone null)
-; CHECK-NEXT:    [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias null, i8* (i8*)* nonnull @bar, i8* nofree nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
-; CHECK-NEXT:    [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
-; CHECK-NEXT:    [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias null, i8* (i8*)* nonnull @buz, i8* nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC2]])
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align 536870912 null)
+; CHECK-NEXT:    [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* nofree nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
+; CHECK-NEXT:    [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
+; CHECK-NEXT:    [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC2]])
 ; CHECK-NEXT:    ret i32 0
 ;
 entry:
@@ -54,7 +54,7 @@ declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*,
 
 define internal i8* @foo(i8* %arg) {
 ; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i8* noalias nofree readnone returned [[ARG:%.*]])
+; CHECK-SAME: (i8* noalias nofree readnone returned align 536870912 [[ARG:%.*]])
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    ret i8* null
 ;

diff  --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll
index f01ae28431d6..e47141ca16a6 100644
--- a/llvm/test/Transforms/Attributor/align.ll
+++ b/llvm/test/Transforms/Attributor/align.ll
@@ -398,6 +398,99 @@ define void @test12-6(i32* align 4 %p) {
   ret void
 }
 
+define void @test13(i1 %c, i32* align 32 %dst) #0 {
+; ATTRIBUTOR-LABEL: define {{[^@]+}}@test13
+; ATTRIBUTOR-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; ATTRIBUTOR-NEXT:    br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; ATTRIBUTOR:       truebb:
+; ATTRIBUTOR-NEXT:    br label [[END:%.*]]
+; ATTRIBUTOR:       falsebb:
+; ATTRIBUTOR-NEXT:    br label [[END]]
+; ATTRIBUTOR:       end:
+; ATTRIBUTOR-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
+; ATTRIBUTOR-NEXT:    store i32 0, i32* [[PTR]], align 32
+; ATTRIBUTOR-NEXT:    ret void
+;
+  br i1 %c, label %truebb, label %falsebb
+truebb:
+  br label %end
+falsebb:
+  br label %end
+end:
+  %ptr = phi i32* [ %dst, %truebb ], [ null, %falsebb ]
+  store i32 0, i32* %ptr
+  ret void
+}
+
+define void @test13-1(i1 %c, i32* align 32 %dst) {
+; ATTRIBUTOR-LABEL: @test13-1(
+; ATTRIBUTOR-NEXT:    br i1 [[C:%.*]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; ATTRIBUTOR:       truebb:
+; ATTRIBUTOR-NEXT:    br label [[END:%.*]]
+; ATTRIBUTOR:       falsebb:
+; ATTRIBUTOR-NEXT:    br label [[END]]
+; ATTRIBUTOR:       end:
+; ATTRIBUTOR-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
+; ATTRIBUTOR-NEXT:    store i32 0, i32* [[PTR]], align 16
+; ATTRIBUTOR-NEXT:    ret void
+;
+  br i1 %c, label %truebb, label %falsebb
+truebb:
+  br label %end
+falsebb:
+  br label %end
+end:
+  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 48 to i32*), %falsebb ]
+  store i32 0, i32* %ptr
+  ret void
+}
+
+define void @test13-2(i1 %c, i32* align 32 %dst) {
+; ATTRIBUTOR-LABEL: @test13-2(
+; ATTRIBUTOR-NEXT:    br i1 [[C:%.*]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; ATTRIBUTOR:       truebb:
+; ATTRIBUTOR-NEXT:    br label [[END:%.*]]
+; ATTRIBUTOR:       falsebb:
+; ATTRIBUTOR-NEXT:    br label [[END]]
+; ATTRIBUTOR:       end:
+; ATTRIBUTOR-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
+; ATTRIBUTOR-NEXT:    store i32 0, i32* [[PTR]], align 32
+; ATTRIBUTOR-NEXT:    ret void
+;
+  br i1 %c, label %truebb, label %falsebb
+truebb:
+  br label %end
+falsebb:
+  br label %end
+end:
+  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 160 to i32*), %falsebb ]
+  store i32 0, i32* %ptr
+  ret void
+}
+
+define void @test13-3(i1 %c, i32* align 32 %dst) {
+; ATTRIBUTOR-LABEL: @test13-3(
+; ATTRIBUTOR-NEXT:    br i1 [[C:%.*]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; ATTRIBUTOR:       truebb:
+; ATTRIBUTOR-NEXT:    br label [[END:%.*]]
+; ATTRIBUTOR:       falsebb:
+; ATTRIBUTOR-NEXT:    br label [[END]]
+; ATTRIBUTOR:       end:
+; ATTRIBUTOR-NEXT:    [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
+; ATTRIBUTOR-NEXT:    store i32 0, i32* [[PTR]], align 32
+; ATTRIBUTOR-NEXT:    ret void
+;
+  br i1 %c, label %truebb, label %falsebb
+truebb:
+  br label %end
+falsebb:
+  br label %end
+end:
+  %ptr = phi i32* [ %dst, %truebb ], [ inttoptr (i64 128 to i32*), %falsebb ]
+  store i32 0, i32* %ptr
+  ret void
+}
+
 ; Don't crash on ptr2int/int2ptr uses.
 define i64 @ptr2int(i32* %p) {
   %p2i = ptrtoint i32* %p to i64
@@ -410,3 +503,4 @@ define i64* @int2ptr(i64 %i) {
 
 attributes #0 = { nounwind uwtable noinline }
 attributes #1 = { uwtable noinline }
+attributes #2 = { "null-pointer-is-valid"="true" }

diff  --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll
index 74c870c7e579..d4487393ddb6 100644
--- a/llvm/test/Transforms/Attributor/callbacks.ll
+++ b/llvm/test/Transforms/Attributor/callbacks.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
 ; FIXME: Add -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations below.
 ;        This flag was removed because max iterations is 2 in most cases, but in windows it is 1.
 ; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s
@@ -15,7 +15,8 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
 ; transfer in both directions.
 
 define void @t0_caller(i32* %a) {
-; CHECK-LABEL: @t0_caller(
+; CHECK-LABEL: define {{[^@]+}}@t0_caller
+; CHECK-SAME: (i32* align 256 [[A:%.*]])
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 32
 ; CHECK-NEXT:    [[C:%.*]] = alloca i32*, align 64
@@ -23,10 +24,10 @@ define void @t0_caller(i32* %a) {
 ; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
 ; CHECK-NEXT:    store i32 42, i32* [[B]], align 32
 ; CHECK-NEXT:    store i32* [[B]], i32** [[C]], align 64
-; CHECK-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A:%.*]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
-
+; CHECK-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
 ; CHECK-NEXT:    ret void
 ;
+
 entry:
   %b = alloca i32, align 32
   %c = alloca i32*, align 64
@@ -44,10 +45,10 @@ define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a,
 ; CHECK-LABEL: define {{[^@]+}}@t0_callback_callee
 ; CHECK-SAME: (i32* nocapture nonnull writeonly dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR:%.*]], align 8
-; CHECK-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL:%.*]]
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C:%.*]], align 64
-; CHECK-NEXT:    tail call void @t0_check(i32* align 256 [[A:%.*]], i64 99, i32* [[TMP0]])
+; CHECK-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
+; CHECK-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
+; CHECK-NEXT:    tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]])
 ; CHECK-NEXT:    ret void
 ;
 entry:

diff  --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll
index 34bdb1c83f5a..135e916cf372 100644
--- a/llvm/test/Transforms/Attributor/nocapture-1.ll
+++ b/llvm/test/Transforms/Attributor/nocapture-1.ll
@@ -322,7 +322,7 @@ declare void @unknown(i8*)
 define void @test_callsite() {
 entry:
 ; We know that 'null' in AS 0 does not alias anything and cannot be captured. Though the latter is not qurried -> derived atm.
-; ATTRIBUTOR: call void @unknown(i8* noalias null)
+; ATTRIBUTOR: call void @unknown(i8* noalias align 536870912 null)
   call void @unknown(i8* null)
   ret void
 }

diff  --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index 519d48bd7579..bf366708c61a 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -23,7 +23,7 @@ define i8* @test2(i8* nonnull %p) {
 ; Given an SCC where one of the functions can not be marked nonnull,
 ; can we still mark the other one which is trivially nonnull
 define i8* @scc_binder(i1 %c) {
-; ATTRIBUTOR: define noalias i8* @scc_binder
+; ATTRIBUTOR: define noalias align 536870912 i8* @scc_binder
   br i1 %c, label %rec, label %end
 rec:
   call i8* @test3(i1 %c)
@@ -57,7 +57,7 @@ define i8* @test4() {
 ; Given a mutual recursive set of functions which *can* return null
 ; make sure we haven't marked them as nonnull.
 define i8* @test5_helper(i1 %c) {
-; ATTRIBUTOR: define noalias i8* @test5_helper
+; ATTRIBUTOR: define noalias align 536870912 i8* @test5_helper
   br i1 %c, label %rec, label %end
 rec:
   %ret = call i8* @test5(i1 %c)
@@ -67,7 +67,7 @@ end:
 }
 
 define i8* @test5(i1 %c) {
-; ATTRIBUTOR: define noalias i8* @test5
+; ATTRIBUTOR: define noalias align 536870912 i8* @test5
   %ret = call i8* @test5_helper(i1 %c)
   ret i8* %ret
 }
@@ -525,7 +525,7 @@ define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) {
   ret i32 addrspace(3)* %p
 }
 
-; ATTRIBUTOR: define internal nonnull i32* @g2()
+; ATTRIBUTOR: define internal nonnull align 4 i32* @g2()
 define internal i32* @g2() {
   ret i32* inttoptr (i64 4 to i32*)
 }

diff  --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll
index 05d4a50af82e..046521a7cd9b 100644
--- a/llvm/test/Transforms/Attributor/value-simplify.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify.ll
@@ -194,14 +194,14 @@ define i32 @ipccp3() {
 %struct.X = type { i8* }
 define internal i32* @test_inalloca(i32* inalloca %a) {
 ; CHECK-LABEL: define {{[^@]+}}@test_inalloca
-; CHECK-SAME: (i32* inalloca noalias nofree returned writeonly [[A:%.*]])
+; CHECK-SAME: (i32* inalloca noalias nofree returned writeonly align 536870912 [[A:%.*]])
 ; CHECK-NEXT:    ret i32* [[A]]
 ;
   ret i32* %a
 }
 define i32* @complicated_args_inalloca() {
 ; CHECK-LABEL: define {{[^@]+}}@complicated_args_inalloca()
-; CHECK-NEXT:    [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree writeonly null)
+; CHECK-NEXT:    [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree writeonly align 536870912 null)
 ; CHECK-NEXT:    ret i32* [[CALL]]
 ;
   %call = call i32* @test_inalloca(i32* null)
@@ -210,7 +210,7 @@ define i32* @complicated_args_inalloca() {
 
 define internal void @test_sret(%struct.X* sret %a, %struct.X** %b) {
 ; CHECK-LABEL: define {{[^@]+}}@test_sret
-; CHECK-SAME: (%struct.X* nofree sret writeonly [[A:%.*]], %struct.X** nocapture nofree nonnull writeonly dereferenceable(8) [[B:%.*]])
+; CHECK-SAME: (%struct.X* nofree sret writeonly align 536870912 [[A:%.*]], %struct.X** nocapture nofree nonnull writeonly dereferenceable(8) [[B:%.*]])
 ; CHECK-NEXT:    store %struct.X* [[A]], %struct.X** [[B]]
 ; CHECK-NEXT:    ret void
 ;
@@ -220,7 +220,7 @@ define internal void @test_sret(%struct.X* sret %a, %struct.X** %b) {
 define void @complicated_args_sret(%struct.X** %b) {
 ; CHECK-LABEL: define {{[^@]+}}@complicated_args_sret
 ; CHECK-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]])
-; CHECK-NEXT:    call void @test_sret(%struct.X* nofree writeonly null, %struct.X** nocapture nofree writeonly [[B]])
+; CHECK-NEXT:    call void @test_sret(%struct.X* nofree writeonly align 536870912 null, %struct.X** nocapture nofree writeonly [[B]])
 ; CHECK-NEXT:    ret void
 ;
   call void @test_sret(%struct.X* null, %struct.X** %b)
@@ -229,14 +229,14 @@ define void @complicated_args_sret(%struct.X** %b) {
 
 define internal %struct.X* @test_nest(%struct.X* nest %a) {
 ; CHECK-LABEL: define {{[^@]+}}@test_nest
-; CHECK-SAME: (%struct.X* nest noalias nofree readnone returned [[A:%.*]])
+; CHECK-SAME: (%struct.X* nest noalias nofree readnone returned align 536870912 [[A:%.*]])
 ; CHECK-NEXT:    ret %struct.X* [[A]]
 ;
   ret %struct.X* %a
 }
 define %struct.X* @complicated_args_nest() {
 ; CHECK-LABEL: define {{[^@]+}}@complicated_args_nest()
-; CHECK-NEXT:    [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nofree readnone null)
+; CHECK-NEXT:    [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nofree readnone align 536870912 null)
 ; CHECK-NEXT:    ret %struct.X* [[CALL]]
 ;
   %call = call %struct.X* @test_nest(%struct.X* null)


        


More information about the llvm-commits mailing list