Files
clang-p2996/llvm/test/Transforms/Attributor/callgraph.ll
Johannes Doerfert fc82409b5c [Attributor] Simplify operands inside of simplification AAs first
When we do simplification via AAPotentialValues or AAValueConstantRange
we need to simplify the operands of an instruction we deconstruct first.
This does not only improve the result, see for example range.ll, but is
required as we allow outside AAs to provide simplification rules via
callbacks. If we do ignore the simplification rules and base other
simplifications on the IR instead we can create an inconsistent state.
2021-07-06 22:41:18 -05:00

108 lines
3.0 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes=attributor -S < %s | FileCheck %s --check-prefixes=CHECK
; RUN: opt -passes=attributor -attributor-print-call-graph -S -disable-output < %s | FileCheck %s --check-prefixes=DOT
define dso_local void @func1() {
; CHECK-LABEL: @func1(
; CHECK-NEXT: br label [[TMP2:%.*]]
; CHECK: 1:
; CHECK-NEXT: unreachable
; CHECK: 2:
; CHECK-NEXT: call void @func3()
; CHECK-NEXT: ret void
;
%1 = icmp ne i32 0, 0
br i1 %1, label %2, label %3
2: ; preds = %0
call void @func2()
br label %3
3: ; preds = %2, %0
call void () @func3()
ret void
}
declare void @func3()
declare void @func4()
define dso_local void @func2() {
; CHECK-LABEL: @func2(
; CHECK-NEXT: call void @func4()
; CHECK-NEXT: ret void
;
call void @func4()
ret void
}
define void @func5(i32 %0) {
; CHECK-LABEL: @func5(
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP0:%.*]], 0
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], void ()* @func4, void ()* @func3
; CHECK-NEXT: call void [[TMP3]]()
; CHECK-NEXT: ret void
;
%2 = icmp ne i32 %0, 0
%3 = select i1 %2, void ()* @func4, void ()* @func3
call void () %3()
ret void
}
define void @broker(void ()* %unknown) !callback !0 {
; CHECK-LABEL: @broker(
; CHECK-NEXT: call void [[UNKNOWN:%.*]]()
; CHECK-NEXT: ret void
;
call void %unknown()
ret void
}
define void @func6() {
; CHECK-LABEL: @func6(
; CHECK-NEXT: call void @broker(void ()* nocapture nofree noundef @func3)
; CHECK-NEXT: ret void
;
call void @broker(void ()* @func3)
ret void
}
define void @func7(void ()* %unknown) {
; CHECK-LABEL: @func7(
; CHECK-NEXT: call void [[UNKNOWN:%.*]](), !callees !2
; CHECK-NEXT: ret void
;
call void %unknown(), !callees !2
ret void
}
!0 = !{!1}
!1 = !{i64 0, i1 false}
!2 = !{void ()* @func3, void ()* @func4}
; UTC_ARGS: --disable
; DOT-DAG: Node[[FUNC1:0x[a-z0-9]+]] [shape=record,label="{func1}"];
; DOT-DAG: Node[[FUNC2:0x[a-z0-9]+]] [shape=record,label="{func2}"];
; DOT-DAG: Node[[FUNC3:0x[a-z0-9]+]] [shape=record,label="{func3}"];
; DOT-DAG: Node[[FUNC4:0x[a-z0-9]+]] [shape=record,label="{func4}"];
; DOT-DAG: Node[[FUNC5:0x[a-z0-9]+]] [shape=record,label="{func5}"];
; DOT-DAG: Node[[FUNC6:0x[a-z0-9]+]] [shape=record,label="{func6}"];
; DOT-DAG: Node[[FUNC7:0x[a-z0-9]+]] [shape=record,label="{func7}"];
; DOT-DAG: Node[[BROKER:0x[a-z0-9]+]] [shape=record,label="{broker}"];
; DOT-DAG: Node[[FUNC1]] -> Node[[FUNC3]];
; DOT-DAG: Node[[FUNC2]] -> Node[[FUNC4]];
; DOT-DAG: Node[[FUNC5]] -> Node[[FUNC3]];
; DOT-DAG: Node[[FUNC5]] -> Node[[FUNC4]];
; DOT-DAG: Node[[FUNC6]] -> Node[[BROKER]];
; This one gets added because of the callback metadata.
; DOT-DAG: Node[[FUNC6]] -> Node[[FUNC3]];
; These ones are added because of the callees metadata.
; DOT-DAG: Node[[FUNC7]] -> Node[[FUNC3]];
; DOT-DAG: Node[[FUNC7]] -> Node[[FUNC4]];