Files
clang-p2996/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
Johannes Doerfert 369930bc20 [Attributor] Manifest attributes implied by the IR
If an attribute is implied by the IR we do not (always) create an AA
anymore. To keep test coverage, and given the lack of a good heuristic
to decide otherwise, we will now also manifest such attributes.
2023-07-03 16:05:17 -07:00

113 lines
4.3 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
define void @f() {
; TUNIT-LABEL: define {{[^@]+}}@f() {
; TUNIT-NEXT: entry:
; TUNIT-NEXT: [[A:%.*]] = alloca i32, align 1
; TUNIT-NEXT: [[TMP0:%.*]] = load i32, ptr [[A]], align 1
; TUNIT-NEXT: call void @g(i32 [[TMP0]])
; TUNIT-NEXT: ret void
;
; CGSCC-LABEL: define {{[^@]+}}@f() {
; CGSCC-NEXT: entry:
; CGSCC-NEXT: call void @g(i32 undef)
; CGSCC-NEXT: ret void
;
entry:
%a = alloca i32, align 1
call void @g(ptr %a)
ret void
}
define internal void @g(ptr %a) {
; CHECK-LABEL: define {{[^@]+}}@g
; CHECK-SAME: (i32 [[TMP0:%.*]]) {
; CHECK-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
; CHECK-NEXT: store i32 [[TMP0]], ptr [[A_PRIV]], align 4
; CHECK-NEXT: [[AA:%.*]] = load i32, ptr [[A_PRIV]], align 1
; CHECK-NEXT: call void @z(i32 [[AA]])
; CHECK-NEXT: ret void
;
%aa = load i32, ptr %a, align 1
call void @z(i32 %aa)
ret void
}
declare void @z(i32)
; Test2
; Different alignemnt privatizable arguments
define internal i32 @test(ptr %X, ptr %Y) {
; CGSCC: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read)
; CGSCC-LABEL: define {{[^@]+}}@test
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64 [[TMP0:%.*]]) #[[ATTR0:[0-9]+]] {
; CGSCC-NEXT: [[Y_PRIV:%.*]] = alloca i64, align 8
; CGSCC-NEXT: store i64 [[TMP0]], ptr [[Y_PRIV]], align 4
; CGSCC-NEXT: [[A:%.*]] = load i32, ptr [[X]], align 4
; CGSCC-NEXT: [[B:%.*]] = load i64, ptr [[Y_PRIV]], align 8
; CGSCC-NEXT: [[C:%.*]] = add i32 [[A]], 1
; CGSCC-NEXT: [[D:%.*]] = add i64 [[B]], 1
; CGSCC-NEXT: [[COND:%.*]] = icmp sgt i64 [[D]], -1
; CGSCC-NEXT: br i1 [[COND]], label [[RETURN1:%.*]], label [[RETURN2:%.*]]
; CGSCC: Return1:
; CGSCC-NEXT: ret i32 [[C]]
; CGSCC: Return2:
; CGSCC-NEXT: ret i32 [[A]]
;
%A = load i32, ptr %X
%B = load i64, ptr %Y
%C = add i32 %A, 1
%D = add i64 %B, 1
%cond = icmp sgt i64 %D, -1
br i1 %cond, label %Return1, label %Return2
Return1:
ret i32 %C
Return2:
ret i32 %A
}
define internal i32 @caller(ptr %A) {
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite)
; CGSCC-LABEL: define {{[^@]+}}@caller
; CGSCC-SAME: (i32 [[TMP0:%.*]]) #[[ATTR1:[0-9]+]] {
; CGSCC-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
; CGSCC-NEXT: store i32 [[TMP0]], ptr [[A_PRIV]], align 4
; CGSCC-NEXT: [[C:%.*]] = call i32 @test(ptr noalias nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A_PRIV]], i64 noundef 1) #[[ATTR3:[0-9]+]]
; CGSCC-NEXT: ret i32 [[C]]
;
%B = alloca i64
store i64 1, ptr %B
%C = call i32 @test(ptr %A, ptr %B)
ret i32 %C
}
define i32 @callercaller() {
; TUNIT: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
; TUNIT-LABEL: define {{[^@]+}}@callercaller
; TUNIT-SAME: () #[[ATTR0:[0-9]+]] {
; TUNIT-NEXT: [[B:%.*]] = alloca i32, align 4
; TUNIT-NEXT: ret i32 3
;
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(none)
; CGSCC-LABEL: define {{[^@]+}}@callercaller
; CGSCC-SAME: () #[[ATTR2:[0-9]+]] {
; CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32 noundef 2) #[[ATTR4:[0-9]+]]
; CGSCC-NEXT: ret i32 [[X]]
;
%B = alloca i32
store i32 2, ptr %B
%X = call i32 @caller(ptr %B)
ret i32 %X
}
;.
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }
;.
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) }
; CGSCC: attributes #[[ATTR2]] = { mustprogress nofree nosync nounwind willreturn memory(none) }
; CGSCC: attributes #[[ATTR3]] = { nofree willreturn memory(read) }
; CGSCC: attributes #[[ATTR4]] = { nofree nounwind willreturn }
;.