Since the information is known we can simply use it at the call site.
This is especially useful for callbacks but also helps regular calls.
The test changes are mechanical.
return AAAlignImpl::manifest(A);
}
+ /// See AbstractAttribute::updateImpl(Attributor &A).
+ ChangeStatus updateImpl(Attributor &A) override {
+ ChangeStatus Changed = AAAlignFloating::updateImpl(A);
+ if (Argument *Arg = getAssociatedArgument()) {
+ const auto &ArgAlignAA = A.getAAFor<AAAlign>(
+ *this, IRPosition::argument(*Arg), /* TrackDependence */ false,
+ DepClassTy::OPTIONAL);
+ takeKnownMaximum(ArgAlignAA.getKnownAlign());
+ }
+ return Changed;
+ }
+
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
};
define void @caller(i32** %Y, %struct.pair* %P) {
; CHECK-LABEL: define {{[^@]+}}@caller
; CHECK-SAME: (i32** nocapture readonly [[Y:%.*]], %struct.pair* nocapture nofree readonly [[P:%.*]])
-; CHECK-NEXT: call void @test(i32** nocapture readonly [[Y]]), !dbg !4
+; CHECK-NEXT: call void @test(i32** nocapture readonly align 8 [[Y]]), !dbg !4
; CHECK-NEXT: call void @test_byval(%struct.pair* nocapture nofree readonly undef), !dbg !5
; CHECK-NEXT: ret void
;
; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32*
-; CHECK-NEXT: call fastcc void @fn1(i32* nofree readonly [[TMP3]])
+; CHECK-NEXT: call fastcc void @fn1(i32* nofree readonly align 4 [[TMP3]])
; CHECK-NEXT: ret i32 undef
;
%1 = load i32, i32* @b, align 4
; each other but argument 3-5 of the transitive call site in the caller match
; arguments 2-4 of the callback callee. Here we should see information and value
; transfer in both directions.
-; FIXME: %a should be align 256 at the call site
define void @t0_caller(i32* %a) {
; CHECK-LABEL: @t0_caller(
; 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* [[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 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
;
; not_captured_but_returned_1(a);
; }
;
-; CHECK: define void @test_not_captured_but_returned_calls(i64* nocapture nofree writeonly %a)
+; CHECK: define void @test_not_captured_but_returned_calls(i64* nocapture nofree writeonly align 8 %a)
define void @test_not_captured_but_returned_calls(i64* %a) #0 {
entry:
%call = call i64* @not_captured_but_returned_0(i64* %a)
; }
;
; There should *not* be a no-capture attribute on %a
-; CHECK: define i64* @negative_test_not_captured_but_returned_call_0a(i64* nofree returned writeonly "no-capture-maybe-returned" %a)
+; CHECK: define align 8 i64* @negative_test_not_captured_but_returned_call_0a(i64* nofree returned writeonly align 8 "no-capture-maybe-returned" %a)
define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 {
entry:
%call = call i64* @not_captured_but_returned_0(i64* %a)
; }
;
; There should *not* be a no-capture attribute on %a
-; CHECK: define void @negative_test_not_captured_but_returned_call_0b(i64* nofree writeonly %a)
+; CHECK: define void @negative_test_not_captured_but_returned_call_0b(i64* nofree writeonly align 8 %a)
define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
entry:
%call = call i64* @not_captured_but_returned_0(i64* %a)
; }
;
; There should *not* be a no-capture attribute on %a
-; CHECK: define nonnull align 8 dereferenceable(8) i64* @negative_test_not_captured_but_returned_call_1a(i64* nofree writeonly "no-capture-maybe-returned" %a)
+; CHECK: define nonnull align 8 dereferenceable(8) i64* @negative_test_not_captured_but_returned_call_1a(i64* nofree writeonly align 8 "no-capture-maybe-returned" %a)
define i64* @negative_test_not_captured_but_returned_call_1a(i64* %a) #0 {
entry:
%call = call i64* @not_captured_but_returned_1(i64* %a)
; }
;
; There should *not* be a no-capture attribute on %a
-; CHECK: define void @negative_test_not_captured_but_returned_call_1b(i64* nofree writeonly %a)
+; CHECK: define void @negative_test_not_captured_but_returned_call_1b(i64* nofree writeonly align 8 %a)
define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 {
entry:
%call = call i64* @not_captured_but_returned_1(i64* %a)