mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-01 05:01:59 +01:00
[AssumeBundles] Add nonnull/align to op bundle if noundef exists
This is a patch to add nonnull and align to assume's operand bundle only if noundef exists. Since nonnull and align in fn attr have poison semantics, they should be paired with noundef or noundef-implying attributes to be immediate UB. Reviewed By: jdoerfert, Tyker Differential Revision: https://reviews.llvm.org/D98228
This commit is contained in:
parent
33c1eeca58
commit
5173305fd6
@ -204,8 +204,12 @@ struct AssumeBuilderState {
|
||||
auto addAttrList = [&](AttributeList AttrList) {
|
||||
for (unsigned Idx = AttributeList::FirstArgIndex;
|
||||
Idx < AttrList.getNumAttrSets(); Idx++)
|
||||
for (Attribute Attr : AttrList.getAttributes(Idx))
|
||||
addAttribute(Attr, Call->getArgOperand(Idx - 1));
|
||||
for (Attribute Attr : AttrList.getAttributes(Idx)) {
|
||||
bool IsPoisonAttr = Attr.hasAttribute(Attribute::NonNull) ||
|
||||
Attr.hasAttribute(Attribute::Alignment);
|
||||
if (!IsPoisonAttr || Call->isPassingUndefUB(Idx - 1))
|
||||
addAttribute(Attr, Call->getArgOperand(Idx - 1));
|
||||
}
|
||||
for (Attribute Attr : AttrList.getFnAttributes())
|
||||
addAttribute(Attr, nullptr);
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
|
||||
; REQUIRES: asserts
|
||||
|
||||
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
|
||||
; 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
|
||||
@ -12,59 +12,69 @@ declare void @func_cold(i32*) cold willreturn nounwind
|
||||
declare void @func_strbool(i32*) "no-jump-tables"
|
||||
declare void @func_many(i32*) "no-jump-tables" nounwind "less-precise-fpmad" willreturn norecurse
|
||||
declare void @func_argattr(i32* align 8, i32* nonnull) nounwind
|
||||
declare void @func_argattr2(i32* noundef align 8, i32* noundef nonnull) nounwind
|
||||
declare void @may_throw()
|
||||
|
||||
define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
; COUNTER1-LABEL: define {{[^@]+}}@test
|
||||
; COUNTER1-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]])
|
||||
; COUNTER1-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
|
||||
; COUNTER1-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
|
||||
; COUNTER1-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
|
||||
; COUNTER1-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) #5
|
||||
; COUNTER1-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR5:#.*]]
|
||||
; COUNTER1-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
|
||||
; COUNTER1-NEXT: call void @func(i32* [[P1]], i32* [[P]])
|
||||
; COUNTER1-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; COUNTER1-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; COUNTER1-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
||||
; COUNTER1-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; COUNTER1-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
|
||||
; COUNTER1-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; COUNTER1-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; COUNTER1-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; COUNTER1-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; COUNTER1-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; COUNTER1-NEXT: ret void
|
||||
;
|
||||
; COUNTER2-LABEL: define {{[^@]+}}@test
|
||||
; COUNTER2-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]])
|
||||
; COUNTER2-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
|
||||
; COUNTER2-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
|
||||
; COUNTER2-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12), "nonnull"(i32* [[P]]) ]
|
||||
; COUNTER2-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12) ]
|
||||
; COUNTER2-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
|
||||
; COUNTER2-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
|
||||
; COUNTER2-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) #5
|
||||
; COUNTER2-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR5:#.*]]
|
||||
; COUNTER2-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
|
||||
; COUNTER2-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
|
||||
; COUNTER2-NEXT: call void @func(i32* [[P1]], i32* [[P]])
|
||||
; COUNTER2-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; COUNTER2-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; COUNTER2-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; COUNTER2-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; COUNTER2-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; COUNTER2-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; COUNTER2-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; COUNTER2-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; COUNTER2-NEXT: ret void
|
||||
;
|
||||
; COUNTER3-LABEL: define {{[^@]+}}@test
|
||||
; COUNTER3-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]])
|
||||
; COUNTER3-SAME: (i32* [[P:%.*]], i32* [[P1:%.*]], i32* [[P2:%.*]], i32* [[P3:%.*]]) {
|
||||
; COUNTER3-NEXT: call void @func(i32* nonnull dereferenceable(16) [[P]], i32* null)
|
||||
; COUNTER3-NEXT: call void @func(i32* dereferenceable(12) [[P1]], i32* nonnull [[P]])
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P1]], i64 12), "cold"() ]
|
||||
; COUNTER3-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) #5
|
||||
; COUNTER3-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]]) [[ATTR5:#.*]]
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "cold"() ]
|
||||
; COUNTER3-NEXT: call void @func_cold(i32* dereferenceable(12) [[P1]])
|
||||
; COUNTER3-NEXT: call void @func(i32* [[P1]], i32* [[P]])
|
||||
; COUNTER3-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
||||
; COUNTER3-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
||||
; COUNTER3-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2]], i64 8), "nonnull"(i32* [[P3]]) ]
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
|
||||
; COUNTER3-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; COUNTER3-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "nonnull"(i32* [[P]]) ]
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
|
||||
; COUNTER3-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; COUNTER3-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; COUNTER3-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]), "nonnull"(i32* [[P]]) ]
|
||||
; COUNTER3-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; COUNTER3-NEXT: ret void
|
||||
;
|
||||
call void @func(i32* nonnull dereferenceable(16) %P, i32* null)
|
||||
@ -75,7 +85,10 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
call void @func_strbool(i32* %P1)
|
||||
call void @func(i32* dereferenceable(32) %P, i32* dereferenceable(8) %P)
|
||||
call void @func_many(i32* align 8 %P1)
|
||||
call void @func_many(i32* align 8 noundef %P1)
|
||||
call void @func_argattr(i32* %P2, i32* %P3)
|
||||
call void @func_argattr2(i32* %P2, i32* %P3)
|
||||
call void @func(i32* nonnull %P1, i32* nonnull %P)
|
||||
call void @func(i32* nonnull noundef %P1, i32* nonnull noundef %P)
|
||||
ret void
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ declare void @func_cold(i32*) cold willreturn nounwind
|
||||
declare void @func_strbool(i32*) "no-jump-tables"
|
||||
declare void @func_many(i32*) "no-jump-tables" nounwind "less-precise-fpmad" willreturn norecurse
|
||||
declare void @func_argattr(i32* align 8, i32* nonnull) nounwind
|
||||
declare void @func_argattr2(i32* noundef align 8, i32* noundef nonnull) nounwind
|
||||
declare void @may_throw()
|
||||
|
||||
define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
@ -35,12 +36,15 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
; BASIC-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
||||
; BASIC-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
||||
; BASIC-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2]], i64 8), "nonnull"(i32* [[P3]]) ]
|
||||
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
|
||||
; BASIC-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; BASIC-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]) ]
|
||||
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
|
||||
; BASIC-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; BASIC-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; BASIC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
|
||||
; BASIC-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; BASIC-NEXT: ret void
|
||||
;
|
||||
; ALL-LABEL: define {{[^@]+}}@test
|
||||
@ -57,12 +61,17 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
; ALL-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
||||
; ALL-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8), "norecurse"(), "nounwind"(), "willreturn"() ]
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "norecurse"(), "nounwind"(), "willreturn"() ]
|
||||
; ALL-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2]], i64 8), "nonnull"(i32* [[P3]]), "nounwind"() ]
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8), "norecurse"(), "nounwind"(), "willreturn"() ]
|
||||
; ALL-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "nounwind"() ]
|
||||
; ALL-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]) ]
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]), "nounwind"() ]
|
||||
; ALL-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; ALL-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; ALL-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
|
||||
; ALL-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; ALL-NEXT: ret void
|
||||
;
|
||||
; WITH-AC-LABEL: define {{[^@]+}}@test
|
||||
@ -79,12 +88,15 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
; WITH-AC-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
||||
; WITH-AC-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
||||
; WITH-AC-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2]], i64 8), "nonnull"(i32* [[P3]]) ]
|
||||
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
|
||||
; WITH-AC-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; WITH-AC-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]) ]
|
||||
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
|
||||
; WITH-AC-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; WITH-AC-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; WITH-AC-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
|
||||
; WITH-AC-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; WITH-AC-NEXT: ret void
|
||||
;
|
||||
; CROSS-BLOCK-LABEL: define {{[^@]+}}@test
|
||||
@ -101,12 +113,15 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
; CROSS-BLOCK-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
||||
; CROSS-BLOCK-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8) ]
|
||||
; CROSS-BLOCK-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P2]], i64 8), "nonnull"(i32* [[P3]]) ]
|
||||
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
|
||||
; CROSS-BLOCK-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; CROSS-BLOCK-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]) ]
|
||||
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
|
||||
; CROSS-BLOCK-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; CROSS-BLOCK-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; CROSS-BLOCK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
|
||||
; CROSS-BLOCK-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; CROSS-BLOCK-NEXT: ret void
|
||||
;
|
||||
; FULL-SIMPLIFY-LABEL: define {{[^@]+}}@test
|
||||
@ -121,11 +136,15 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
; FULL-SIMPLIFY-NEXT: call void @func_strbool(i32* [[P1]])
|
||||
; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[P]], i64 32) ]
|
||||
; FULL-SIMPLIFY-NEXT: call void @func(i32* dereferenceable(32) [[P]], i32* dereferenceable(8) [[P]])
|
||||
; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "align"(i32* [[P1]], i64 8), "align"(i32* [[P2]], i64 8), "nonnull"(i32* [[P3]]) ]
|
||||
; FULL-SIMPLIFY-NEXT: call void @func_many(i32* align 8 [[P1]])
|
||||
; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P1]]), "align"(i32* [[P1]], i64 8) ]
|
||||
; FULL-SIMPLIFY-NEXT: call void @func_many(i32* noundef align 8 [[P1]])
|
||||
; FULL-SIMPLIFY-NEXT: call void @func_argattr(i32* [[P2]], i32* [[P3]])
|
||||
; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]) ]
|
||||
; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "noundef"(i32* [[P2]]), "align"(i32* [[P2]], i64 8), "noundef"(i32* [[P3]]), "nonnull"(i32* [[P3]]) ]
|
||||
; FULL-SIMPLIFY-NEXT: call void @func_argattr2(i32* [[P2]], i32* [[P3]])
|
||||
; FULL-SIMPLIFY-NEXT: call void @func(i32* nonnull [[P1]], i32* nonnull [[P]])
|
||||
; FULL-SIMPLIFY-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i32* [[P1]]), "noundef"(i32* [[P]]) ]
|
||||
; FULL-SIMPLIFY-NEXT: call void @func(i32* noundef nonnull [[P1]], i32* noundef nonnull [[P]])
|
||||
; FULL-SIMPLIFY-NEXT: ret void
|
||||
;
|
||||
call void @func(i32* nonnull dereferenceable(16) %P, i32* null)
|
||||
@ -136,8 +155,11 @@ define void @test(i32* %P, i32* %P1, i32* %P2, i32* %P3) {
|
||||
call void @func_strbool(i32* %P1)
|
||||
call void @func(i32* dereferenceable(32) %P, i32* dereferenceable(8) %P)
|
||||
call void @func_many(i32* align 8 %P1)
|
||||
call void @func_many(i32* align 8 noundef %P1)
|
||||
call void @func_argattr(i32* %P2, i32* %P3)
|
||||
call void @func_argattr2(i32* %P2, i32* %P3)
|
||||
call void @func(i32* nonnull %P1, i32* nonnull %P)
|
||||
call void @func(i32* nonnull noundef %P1, i32* nonnull noundef %P)
|
||||
ret void
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) {
|
||||
EnableKnowledgeRetention.setValue(true);
|
||||
StringRef Head =
|
||||
"declare void @llvm.assume(i1)\n"
|
||||
"declare void @func(i32*, i32*)\n"
|
||||
"declare void @func(i32*, i32*, i32*)\n"
|
||||
"declare void @func1(i32*, i32*, i32*, i32*)\n"
|
||||
"declare void @func_many(i32*) \"no-jump-tables\" nounwind "
|
||||
"\"less-precise-fpmad\" willreturn norecurse\n"
|
||||
@ -82,14 +82,16 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) {
|
||||
Tests;
|
||||
Tests.push_back(std::make_pair(
|
||||
"call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align "
|
||||
"8 noalias %P1)\n",
|
||||
"8 noalias %P1, i32* align 8 noundef %P2)\n",
|
||||
[](Instruction *I) {
|
||||
IntrinsicInst *Assume = buildAssumeFromInst(I);
|
||||
Assume->insertBefore(I);
|
||||
ASSERT_TRUE(hasMatchesExactlyAttributes(Assume, I->getOperand(0),
|
||||
"(nonnull|align|dereferenceable)"));
|
||||
ASSERT_TRUE(hasMatchesExactlyAttributes(Assume, I->getOperand(1),
|
||||
"(align)"));
|
||||
"()"));
|
||||
ASSERT_TRUE(hasMatchesExactlyAttributes(Assume, I->getOperand(2),
|
||||
"(align|noundef)"));
|
||||
ASSERT_TRUE(hasTheRightValue(Assume, I->getOperand(0),
|
||||
Attribute::AttrKind::Dereferenceable, 16));
|
||||
ASSERT_TRUE(hasTheRightValue(Assume, I->getOperand(0),
|
||||
@ -122,12 +124,13 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) {
|
||||
Attribute::AttrKind::Alignment, 64));
|
||||
}));
|
||||
Tests.push_back(std::make_pair(
|
||||
"call void @func_many(i32* align 8 %P1) cold\n", [](Instruction *I) {
|
||||
"call void @func_many(i32* align 8 noundef %P1) cold\n", [](Instruction *I) {
|
||||
ShouldPreserveAllAttributes.setValue(true);
|
||||
IntrinsicInst *Assume = buildAssumeFromInst(I);
|
||||
Assume->insertBefore(I);
|
||||
ASSERT_TRUE(hasMatchesExactlyAttributes(
|
||||
Assume, nullptr, "(align|nounwind|norecurse|willreturn|cold)"));
|
||||
Assume, nullptr,
|
||||
"(align|nounwind|norecurse|noundef|willreturn|cold)"));
|
||||
ShouldPreserveAllAttributes.setValue(false);
|
||||
}));
|
||||
Tests.push_back(
|
||||
@ -199,7 +202,7 @@ TEST(AssumeQueryAPI, hasAttributeInAssume) {
|
||||
}));
|
||||
Tests.push_back(std::make_pair(
|
||||
"call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align "
|
||||
"8 noalias %P1)\n",
|
||||
"8 noalias %P1, i32* %P1)\n",
|
||||
[](Instruction *I) {
|
||||
IntrinsicInst *Assume = buildAssumeFromInst(I);
|
||||
Assume->insertBefore(I);
|
||||
@ -244,7 +247,7 @@ TEST(AssumeQueryAPI, fillMapFromAssume) {
|
||||
EnableKnowledgeRetention.setValue(true);
|
||||
StringRef Head =
|
||||
"declare void @llvm.assume(i1)\n"
|
||||
"declare void @func(i32*, i32*)\n"
|
||||
"declare void @func(i32*, i32*, i32*)\n"
|
||||
"declare void @func1(i32*, i32*, i32*, i32*)\n"
|
||||
"declare void @func_many(i32*) \"no-jump-tables\" nounwind "
|
||||
"\"less-precise-fpmad\" willreturn norecurse\n"
|
||||
@ -255,7 +258,7 @@ TEST(AssumeQueryAPI, fillMapFromAssume) {
|
||||
Tests;
|
||||
Tests.push_back(std::make_pair(
|
||||
"call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align "
|
||||
"8 noalias %P1)\n",
|
||||
"8 noalias %P1, i32* align 8 dereferenceable(8) %P2)\n",
|
||||
[](Instruction *I) {
|
||||
IntrinsicInst *Assume = buildAssumeFromInst(I);
|
||||
Assume->insertBefore(I);
|
||||
@ -264,8 +267,10 @@ TEST(AssumeQueryAPI, fillMapFromAssume) {
|
||||
fillMapFromAssume(*Assume, Map);
|
||||
ASSERT_TRUE(FindExactlyAttributes(Map, I->getOperand(0),
|
||||
"(nonnull|align|dereferenceable)"));
|
||||
ASSERT_TRUE(FindExactlyAttributes(Map, I->getOperand(1),
|
||||
ASSERT_FALSE(FindExactlyAttributes(Map, I->getOperand(1),
|
||||
"(align)"));
|
||||
ASSERT_TRUE(FindExactlyAttributes(Map, I->getOperand(2),
|
||||
"(align|dereferenceable)"));
|
||||
ASSERT_TRUE(MapHasRightValue(
|
||||
Map, Assume, {I->getOperand(0), Attribute::Dereferenceable}, {16, 16}));
|
||||
ASSERT_TRUE(MapHasRightValue(Map, Assume, {I->getOperand(0), Attribute::Alignment},
|
||||
@ -363,7 +368,7 @@ TEST(AssumeQueryAPI, fillMapFromAssume) {
|
||||
/// Keep this test last as it modifies the function.
|
||||
Tests.push_back(std::make_pair(
|
||||
"call void @func(i32* nonnull align 4 dereferenceable(16) %P, i32* align "
|
||||
"8 noalias %P1)\n",
|
||||
"8 noalias %P1, i32* %P2)\n",
|
||||
[](Instruction *I) {
|
||||
IntrinsicInst *Assume = buildAssumeFromInst(I);
|
||||
Assume->insertBefore(I);
|
||||
|
Loading…
x
Reference in New Issue
Block a user