Files
clang-p2996/llvm/test/Transforms/Attributor/wrapper.ll
Johannes Doerfert c2281f1565 [Attributor] Introduce AAPointerInfo
This patch introduces AAPointerInfo which tracks the uses of a pointer
and places them in "bins" based on their offset from the base and access
size.

As with other AAs, any pointer can be tracked but it is up to the user
to make sense of the results. The user in this patch is AAValueSimplify
and AAPotentialValues which both utilize AAPointerInfo to determine the
value of a load. For now, this is restricted to loads of allocas and
internal globals. Through the use of AAPointerInfo and the "bins" we can
track struct members separately. The users also know that storing only
zeros (at unknown indices) will result in loading only 0 (from unknown
indices). Other than that, the users are flow and context insensitive
(for now).

To deal with the "bins" more easily, AAPointerInfo provides a
forallInterfearingAccesses that applies a callback on all accesses
that might interfere with a given load or store.

Differential Revision: https://reviews.llvm.org/D104432
2021-07-19 22:48:35 -05:00

88 lines
2.1 KiB
LLVM

; RUN: opt -passes=attributor-cgscc -attributor-annotate-decl-cs -attributor-allow-shallow-wrappers -S < %s | FileCheck %s --check-prefix=CHECK
; TEST 1: simple test, without argument
; A wrapper will be generated for this function, Check the wrapper first
; CHECK-NOT: Function Attrs:
; CHECK: define linkonce i32 @inner1()
; CHECK: tail call i32 @0()
; CHECK: ret
;
; Check the original function, which is wrapped and becomes anonymous
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK: define internal noundef i32 @0()
; CHECK: %a = alloca i32
; CHECK: store i32 1, i32* %a
; CHECK: ret i32 1
define linkonce i32 @inner1() {
entry:
%a = alloca i32
store i32 1, i32* %a
%b = load i32, i32* %a
ret i32 %b
}
; Check for call
; CHECK: define i32 @outer1
; CHECK: call i32 @inner1
; CHECK: ret
define i32 @outer1() {
entry:
%ret = call i32 @inner1()
ret i32 %ret
}
; TEST 2: with argument
; CHECK-NOT: Function Attrs
; CHECK: define linkonce i32 @inner2(i32 %a, i32 %b)
; CHECK: tail call i32 @1(i32 %a, i32 %b)
; CHECK: ret
;
; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; CHECK: define internal i32 @1(i32 %a, i32 %b)
; CHECK: %c = add i32 %a, %b
; CHECK: ret i32 %c
define linkonce i32 @inner2(i32 %a, i32 %b) {
entry:
%c = add i32 %a, %b
ret i32 %c
}
; CHECK: define i32 @outer2
; CHECK: call i32 @inner2
; CHECK: ret
define i32 @outer2() {
entry:
%ret = call i32 @inner2(i32 1, i32 2)
ret i32 %ret
}
; TEST 3: check nocurse
; This function calls itself, there will be no attribute
; CHECK-NOT: Function Attrs
; CHECK: define linkonce i32 @inner3(i32 %0)
; CHECK: tail call i32 @2(i32 %0)
; CHECK: ret
;
; CHECK-NOT: Function Attrs:
; CHECK: define internal i32 @2(i32 %0)
define linkonce i32 @inner3(i32) {
entry:
%1 = alloca i32
store i32 %0, i32* %1
br label %2
2:
%3 = load i32, i32* %1
%4 = icmp slt i32 %3, 4
br i1 %4, label %5, label %9
5:
%6 = load i32, i32* %1
%7 = add nsw i32 %6, 1
%8 = call i32 @inner3(i32 %7)
store i32 %8, i32* %1
br label %2
9:
%10 = load i32, i32* %1
ret i32 %10
}