| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature |
| ; REQUIRES: asserts |
| |
| ; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --debug-counter=assume-builder-counter-skip=5,assume-builder-counter-count=1 -S %s | FileCheck %s --check-prefixes=COUNTER1 |
| ; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --debug-counter=assume-builder-counter-skip=1,assume-builder-counter-count=3 -S %s | FileCheck %s --check-prefixes=COUNTER2 |
| ; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --debug-counter=assume-builder-counter-skip=2,assume-builder-counter-count=200 -S %s | FileCheck %s --check-prefixes=COUNTER3 |
| |
| target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" |
| |
| declare void @func(ptr, ptr) |
| declare void @func_cold(ptr) cold willreturn nounwind |
| declare void @func_strbool(ptr) "no-jump-tables" |
| declare void @func_many(ptr) "no-jump-tables" nounwind "less-precise-fpmad" willreturn norecurse |
| declare void @func_argattr(ptr align 8, ptr nonnull) nounwind |
| declare void @func_argattr2(ptr noundef align 8, ptr noundef nonnull) nounwind |
| declare void @may_throw() |
| |
| define void @test(ptr %P, ptr %P1, ptr %P2, ptr %P3) { |
| ; COUNTER1-LABEL: define {{[^@]+}}@test |
| ; COUNTER1-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) { |
| ; COUNTER1-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null) |
| ; COUNTER1-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]]) |
| ; COUNTER1-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) [[ATTR5:#.*]] |
| ; COUNTER1-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) |
| ; COUNTER1-NEXT: call void @func(ptr [[P1]], ptr [[P]]) |
| ; COUNTER1-NEXT: call void @func_strbool(ptr [[P1]]) |
| ; COUNTER1-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]]) |
| ; COUNTER1-NEXT: call void @func_many(ptr align 8 [[P1]]) |
| ; COUNTER1-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ] |
| ; COUNTER1-NEXT: call void @func_many(ptr noundef align 8 [[P1]]) |
| ; COUNTER1-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]]) |
| ; COUNTER1-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]]) |
| ; COUNTER1-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]]) |
| ; COUNTER1-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]]) |
| ; COUNTER1-NEXT: ret void |
| ; |
| ; COUNTER2-LABEL: define {{[^@]+}}@test |
| ; COUNTER2-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) { |
| ; COUNTER2-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null) |
| ; COUNTER2-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 12) ] |
| ; COUNTER2-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]]) |
| ; COUNTER2-NEXT: call void @llvm.assume(i1 true) [ "cold"() ] |
| ; COUNTER2-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) [[ATTR5:#.*]] |
| ; COUNTER2-NEXT: call void @llvm.assume(i1 true) [ "cold"() ] |
| ; COUNTER2-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) |
| ; COUNTER2-NEXT: call void @func(ptr [[P1]], ptr [[P]]) |
| ; COUNTER2-NEXT: call void @func_strbool(ptr [[P1]]) |
| ; COUNTER2-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]]) |
| ; COUNTER2-NEXT: call void @func_many(ptr align 8 [[P1]]) |
| ; COUNTER2-NEXT: call void @func_many(ptr noundef align 8 [[P1]]) |
| ; COUNTER2-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]]) |
| ; COUNTER2-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]]) |
| ; COUNTER2-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]]) |
| ; COUNTER2-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]]) |
| ; COUNTER2-NEXT: ret void |
| ; |
| ; COUNTER3-LABEL: define {{[^@]+}}@test |
| ; COUNTER3-SAME: (ptr [[P:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) { |
| ; COUNTER3-NEXT: call void @func(ptr nonnull dereferenceable(16) [[P]], ptr null) |
| ; COUNTER3-NEXT: call void @func(ptr dereferenceable(12) [[P1]], ptr nonnull [[P]]) |
| ; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P1]], i64 12), "cold"() ] |
| ; COUNTER3-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) [[ATTR5:#.*]] |
| ; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "cold"() ] |
| ; COUNTER3-NEXT: call void @func_cold(ptr dereferenceable(12) [[P1]]) |
| ; COUNTER3-NEXT: call void @func(ptr [[P1]], ptr [[P]]) |
| ; COUNTER3-NEXT: call void @func_strbool(ptr [[P1]]) |
| ; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 32) ] |
| ; COUNTER3-NEXT: call void @func(ptr dereferenceable(32) [[P]], ptr dereferenceable(8) [[P]]) |
| ; COUNTER3-NEXT: call void @func_many(ptr align 8 [[P1]]) |
| ; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P1]]), "align"(ptr [[P1]], i64 8) ] |
| ; COUNTER3-NEXT: call void @func_many(ptr noundef align 8 [[P1]]) |
| ; COUNTER3-NEXT: call void @func_argattr(ptr [[P2]], ptr [[P3]]) |
| ; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "noundef"(ptr [[P2]]), "align"(ptr [[P2]], i64 8), "noundef"(ptr [[P3]]), "nonnull"(ptr [[P3]]) ] |
| ; COUNTER3-NEXT: call void @func_argattr2(ptr [[P2]], ptr [[P3]]) |
| ; COUNTER3-NEXT: call void @func(ptr nonnull [[P1]], ptr nonnull [[P]]) |
| ; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(ptr [[P1]]), "noundef"(ptr [[P]]), "nonnull"(ptr [[P]]) ] |
| ; COUNTER3-NEXT: call void @func(ptr noundef nonnull [[P1]], ptr noundef nonnull [[P]]) |
| ; COUNTER3-NEXT: ret void |
| ; |
| call void @func(ptr nonnull dereferenceable(16) %P, ptr null) |
| call void @func(ptr dereferenceable(12) %P1, ptr nonnull %P) |
| call void @func_cold(ptr dereferenceable(12) %P1) cold |
| call void @func_cold(ptr dereferenceable(12) %P1) |
| call void @func(ptr %P1, ptr %P) |
| call void @func_strbool(ptr %P1) |
| call void @func(ptr dereferenceable(32) %P, ptr dereferenceable(8) %P) |
| call void @func_many(ptr align 8 %P1) |
| call void @func_many(ptr align 8 noundef %P1) |
| call void @func_argattr(ptr %P2, ptr %P3) |
| call void @func_argattr2(ptr %P2, ptr %P3) |
| call void @func(ptr nonnull %P1, ptr nonnull %P) |
| call void @func(ptr nonnull noundef %P1, ptr nonnull noundef %P) |
| ret void |
| } |