1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[AssumeBundles] Preserve Information in the inliner

Summary:
during inling Create and insert an llvm.assume with attributes to preserve them.
to prevent any changes for now generation of llvm.assume is under a flag disabled by default.

Reviewers: jdoerfert

Reviewed By: jdoerfert

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D75825
This commit is contained in:
Tyker 2020-03-13 14:14:55 +01:00
parent 685f5dc624
commit f0d2f70372
6 changed files with 168 additions and 67 deletions

View File

@ -20,6 +20,11 @@ cl::opt<bool> ShouldPreserveAllAttributes(
cl::desc("enable preservation of all attrbitues. even those that are "
"unlikely to be usefull"));
cl::opt<bool> EnableKnowledgeRetention(
"enable-knowledge-retention", cl::init(false), cl::Hidden,
cl::desc(
"enable preservation of attributes throughout code transformation"));
namespace {
struct AssumedKnowledge {
@ -166,6 +171,8 @@ struct AssumeBuilderState {
} // namespace
CallInst *llvm::BuildAssumeFromInst(const Instruction *I, Module *M) {
if (!EnableKnowledgeRetention)
return nullptr;
AssumeBuilderState Builder(M);
Builder.addInstruction(I);
return Builder.build();

View File

@ -50,6 +50,7 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/KnowledgeRetention.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
@ -1695,11 +1696,16 @@ llvm::InlineResult llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI,
VMap[&*I] = ActualArg;
}
// TODO: Remove this when users have been updated to the assume bundles.
// Add alignment assumptions if necessary. We do this before the inlined
// instructions are actually cloned into the caller so that we can easily
// check what will be known at the start of the inlined code.
AddAlignmentAssumptions(CS, IFI);
/// Preserve all attributes on of the call and its parameters.
if (Instruction *Assume = BuildAssumeFromInst(CS.getInstruction()))
Assume->insertBefore(CS.getInstruction());
// We want the inliner to prune the code as it copies. We would LOVE to
// have no dead or constant instructions leftover after inlining occurs
// (which can happen, e.g., because an argument was constant), but we'll be

View File

@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt -passes='assume-builder,verify' -S %s | FileCheck %s --check-prefixes=BASIC
; RUN: opt -passes='assume-builder,verify' --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention -S %s | FileCheck %s --check-prefixes=BASIC
; RUN: opt -passes='assume-builder,verify' --enable-knowledge-retention --assume-preserve-all -S %s | FileCheck %s --check-prefixes=ALL
declare void @func(i32*, i32*)
declare void @func_cold(i32*) cold

View File

@ -1,11 +1,14 @@
; RUN: opt -inline -S < %s | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; RUN: opt -inline -S < %s | FileCheck --check-prefixes=CHECK,NO_ASSUME %s
; RUN: opt -inline -S --enable-knowledge-retention < %s | FileCheck %s --check-prefixes=CHECK,USE_ASSUME
; The callee guarantees that the pointer argument is nonnull and dereferenceable.
; That information should transfer to the caller.
define i32 @callee(i32* dereferenceable(32) %t1) {
; CHECK-LABEL: @callee(i32* dereferenceable(32) %t1)
; CHECK-NEXT: [[T2:%.*]] = load i32, i32* %t1
; CHECK-LABEL: define {{[^@]+}}@callee
; CHECK-SAME: (i32* dereferenceable(32) [[T1:%.*]])
; CHECK-NEXT: [[T2:%.*]] = load i32, i32* [[T1]]
; CHECK-NEXT: ret i32 [[T2]]
;
%t2 = load i32, i32* %t1
@ -16,9 +19,16 @@ define i32 @callee(i32* dereferenceable(32) %t1) {
; The caller argument could be known nonnull and dereferenceable(32).
define i32 @caller1(i32* %t1) {
; CHECK-LABEL: @caller1(i32* %t1)
; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1
; CHECK-NEXT: ret i32 [[T2_I]]
; NO_ASSUME-LABEL: define {{[^@]+}}@caller1
; NO_ASSUME-SAME: (i32* [[T1:%.*]])
; NO_ASSUME-NEXT: [[T2_I:%.*]] = load i32, i32* [[T1]]
; NO_ASSUME-NEXT: ret i32 [[T2_I]]
;
; USE_ASSUME-LABEL: define {{[^@]+}}@caller1
; USE_ASSUME-SAME: (i32* [[T1:%.*]])
; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[T1]], i64 32) ]
; USE_ASSUME-NEXT: [[T2_I:%.*]] = load i32, i32* [[T1]]
; USE_ASSUME-NEXT: ret i32 [[T2_I]]
;
%t2 = tail call i32 @callee(i32* dereferenceable(32) %t1)
ret i32 %t2
@ -28,9 +38,16 @@ define i32 @caller1(i32* %t1) {
; The dereferenceable amount could be increased.
define i32 @caller2(i32* dereferenceable(31) %t1) {
; CHECK-LABEL: @caller2(i32* dereferenceable(31) %t1)
; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1
; CHECK-NEXT: ret i32 [[T2_I]]
; NO_ASSUME-LABEL: define {{[^@]+}}@caller2
; NO_ASSUME-SAME: (i32* dereferenceable(31) [[T1:%.*]])
; NO_ASSUME-NEXT: [[T2_I:%.*]] = load i32, i32* [[T1]]
; NO_ASSUME-NEXT: ret i32 [[T2_I]]
;
; USE_ASSUME-LABEL: define {{[^@]+}}@caller2
; USE_ASSUME-SAME: (i32* dereferenceable(31) [[T1:%.*]])
; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[T1]], i64 32) ]
; USE_ASSUME-NEXT: [[T2_I:%.*]] = load i32, i32* [[T1]]
; USE_ASSUME-NEXT: ret i32 [[T2_I]]
;
%t2 = tail call i32 @callee(i32* dereferenceable(32) %t1)
ret i32 %t2
@ -40,9 +57,16 @@ define i32 @caller2(i32* dereferenceable(31) %t1) {
; Make sure that we don't propagate a smaller dereferenceable amount.
define i32 @caller3(i32* dereferenceable(33) %t1) {
; CHECK-LABEL: @caller3(i32* dereferenceable(33) %t1)
; CHECK-NEXT: [[T2_I:%.*]] = load i32, i32* %t1
; CHECK-NEXT: ret i32 [[T2_I]]
; NO_ASSUME-LABEL: define {{[^@]+}}@caller3
; NO_ASSUME-SAME: (i32* dereferenceable(33) [[T1:%.*]])
; NO_ASSUME-NEXT: [[T2_I:%.*]] = load i32, i32* [[T1]]
; NO_ASSUME-NEXT: ret i32 [[T2_I]]
;
; USE_ASSUME-LABEL: define {{[^@]+}}@caller3
; USE_ASSUME-SAME: (i32* dereferenceable(33) [[T1:%.*]])
; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i32* [[T1]], i64 32) ]
; USE_ASSUME-NEXT: [[T2_I:%.*]] = load i32, i32* [[T1]]
; USE_ASSUME-NEXT: ret i32 [[T2_I]]
;
%t2 = tail call i32 @callee(i32* dereferenceable(32) %t1)
ret i32 %t2

View File

@ -1,8 +1,25 @@
; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s --check-prefixes=CHECK,NO_ASSUME
; RUN: opt -inline -enable-noalias-to-md-conversion --enable-knowledge-retention -S < %s | FileCheck %s --check-prefixes=CHECK,USE_ASSUME
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @hello(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 {
; CHECK-LABEL: define {{[^@]+}}@hello
; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX]], align 4
; CHECK-NEXT: ret void
;
; ASSUME-LABEL: @hello(
; ASSUME-NEXT: entry:
; ASSUME-NEXT: [[TMP0:%.*]] = load float, float* [[C:%.*]], align 4
; ASSUME-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A:%.*]], i64 5
; ASSUME-NEXT: store float [[TMP0]], float* [[ARRAYIDX]], align 4
; ASSUME-NEXT: ret void
entry:
%0 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 5
@ -11,6 +28,29 @@ entry:
}
define void @foo(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 {
; NO_ASSUME-LABEL: define {{[^@]+}}@foo
; NO_ASSUME-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) #0
; NO_ASSUME-NEXT: entry:
; NO_ASSUME-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !0, !noalias !3
; NO_ASSUME-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; NO_ASSUME-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !3, !noalias !0
; NO_ASSUME-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4
; NO_ASSUME-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; NO_ASSUME-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4
; NO_ASSUME-NEXT: ret void
;
; USE_ASSUME-LABEL: define {{[^@]+}}@foo
; USE_ASSUME-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture readonly [[C:%.*]]) #0
; USE_ASSUME-NEXT: entry:
; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "noalias"(float* [[A]]), "noalias"(float* [[C]]), "nocapture"(float* [[A]]), "nocapture"(float* [[C]]), "readonly"(float* [[C]]) ]
; USE_ASSUME-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !0, !noalias !3
; USE_ASSUME-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; USE_ASSUME-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4, !alias.scope !3, !noalias !0
; USE_ASSUME-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4
; USE_ASSUME-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; USE_ASSUME-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4
; USE_ASSUME-NEXT: ret void
;
entry:
tail call void @hello(float* %a, float* %c)
%0 = load float, float* %c, align 4
@ -19,18 +59,17 @@ entry:
ret void
}
; CHECK: define void @foo(float* noalias nocapture %a, float* noalias nocapture readonly %c) #0 {
; CHECK: entry:
; CHECK: %0 = load float, float* %c, align 4, !alias.scope !0, !noalias !3
; CHECK: %arrayidx.i = getelementptr inbounds float, float* %a, i64 5
; CHECK: store float %0, float* %arrayidx.i, align 4, !alias.scope !3, !noalias !0
; CHECK: %1 = load float, float* %c, align 4
; CHECK: %arrayidx = getelementptr inbounds float, float* %a, i64 7
; CHECK: store float %1, float* %arrayidx, align 4
; CHECK: ret void
; CHECK: }
define void @hello2(float* noalias nocapture %a, float* noalias nocapture %b, float* nocapture readonly %c) #0 {
; CHECK-LABEL: define {{[^@]+}}@hello2
; CHECK-SAME: (float* noalias nocapture [[A:%.*]], float* noalias nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 6
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX1]], align 4
; CHECK-NEXT: ret void
;
entry:
%0 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 6
@ -43,6 +82,47 @@ entry:
; Check that when hello() is inlined into foo(), and then foo() is inlined into
; foo2(), the noalias scopes are properly concatenated.
define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
; NO_ASSUME-LABEL: define {{[^@]+}}@foo2
; NO_ASSUME-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #0
; NO_ASSUME-NEXT: entry:
; NO_ASSUME-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !5, !noalias !10
; NO_ASSUME-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; NO_ASSUME-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !10, !noalias !5
; NO_ASSUME-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4, !alias.scope !13, !noalias !14
; NO_ASSUME-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; NO_ASSUME-NEXT: store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !alias.scope !14, !noalias !13
; NO_ASSUME-NEXT: [[TMP2:%.*]] = load float, float* [[C]], align 4, !noalias !15
; NO_ASSUME-NEXT: [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[A]], i64 6
; NO_ASSUME-NEXT: store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4, !alias.scope !19, !noalias !20
; NO_ASSUME-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
; NO_ASSUME-NEXT: store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !20, !noalias !19
; NO_ASSUME-NEXT: [[TMP3:%.*]] = load float, float* [[C]], align 4
; NO_ASSUME-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; NO_ASSUME-NEXT: store float [[TMP3]], float* [[ARRAYIDX]], align 4
; NO_ASSUME-NEXT: ret void
;
; USE_ASSUME-LABEL: define {{[^@]+}}@foo2
; USE_ASSUME-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #0
; USE_ASSUME-NEXT: entry:
; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "noalias"(float* [[A]]), "noalias"(float* [[C]]), "nocapture"(float* [[A]]), "nocapture"(float* [[C]]), "readonly"(float* [[C]]) ]
; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) #2 [ "noalias"(float* [[A]]), "noalias"(float* [[C]]), "nocapture"(float* [[A]]), "nocapture"(float* [[C]]), "readonly"(float* [[C]]) ], !noalias !5
; USE_ASSUME-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4, !alias.scope !9, !noalias !12
; USE_ASSUME-NEXT: [[ARRAYIDX_I_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; USE_ASSUME-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I_I]], align 4, !alias.scope !12, !noalias !9
; USE_ASSUME-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4, !alias.scope !14, !noalias !15
; USE_ASSUME-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; USE_ASSUME-NEXT: store float [[TMP1]], float* [[ARRAYIDX_I]], align 4, !alias.scope !15, !noalias !14
; USE_ASSUME-NEXT: call void @llvm.assume(i1 true) [ "noalias"(float* [[A]]), "noalias"(float* [[B]]), "nocapture"(float* [[A]]), "nocapture"(float* [[B]]), "nocapture"(float* [[C]]), "readonly"(float* [[C]]) ]
; USE_ASSUME-NEXT: [[TMP2:%.*]] = load float, float* [[C]], align 4, !noalias !16
; USE_ASSUME-NEXT: [[ARRAYIDX_I1:%.*]] = getelementptr inbounds float, float* [[A]], i64 6
; USE_ASSUME-NEXT: store float [[TMP2]], float* [[ARRAYIDX_I1]], align 4, !alias.scope !20, !noalias !21
; USE_ASSUME-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
; USE_ASSUME-NEXT: store float [[TMP2]], float* [[ARRAYIDX1_I]], align 4, !alias.scope !21, !noalias !20
; USE_ASSUME-NEXT: [[TMP3:%.*]] = load float, float* [[C]], align 4
; USE_ASSUME-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; USE_ASSUME-NEXT: store float [[TMP3]], float* [[ARRAYIDX]], align 4
; USE_ASSUME-NEXT: ret void
;
entry:
tail call void @foo(float* %a, float* %c)
tail call void @hello2(float* %a, float* %b, float* %c)
@ -52,46 +132,27 @@ entry:
ret void
}
; CHECK: define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
; CHECK: entry:
; CHECK: %0 = load float, float* %c, align 4, !alias.scope !5, !noalias !10
; CHECK: %arrayidx.i.i = getelementptr inbounds float, float* %a, i64 5
; CHECK: store float %0, float* %arrayidx.i.i, align 4, !alias.scope !10, !noalias !5
; CHECK: %1 = load float, float* %c, align 4, !alias.scope !13, !noalias !14
; CHECK: %arrayidx.i = getelementptr inbounds float, float* %a, i64 7
; CHECK: store float %1, float* %arrayidx.i, align 4, !alias.scope !14, !noalias !13
; CHECK: %2 = load float, float* %c, align 4, !noalias !15
; CHECK: %arrayidx.i1 = getelementptr inbounds float, float* %a, i64 6
; CHECK: store float %2, float* %arrayidx.i1, align 4, !alias.scope !19, !noalias !20
; CHECK: %arrayidx1.i = getelementptr inbounds float, float* %b, i64 8
; CHECK: store float %2, float* %arrayidx1.i, align 4, !alias.scope !20, !noalias !19
; CHECK: %3 = load float, float* %c, align 4
; CHECK: %arrayidx = getelementptr inbounds float, float* %a, i64 7
; CHECK: store float %3, float* %arrayidx, align 4
; CHECK: ret void
; CHECK: }
; CHECK: !0 = !{!1}
; CHECK: !1 = distinct !{!1, !2, !"hello: %c"}
; CHECK: !2 = distinct !{!2, !"hello"}
; CHECK: !3 = !{!4}
; CHECK: !4 = distinct !{!4, !2, !"hello: %a"}
; CHECK: !5 = !{!6, !8}
; CHECK: !6 = distinct !{!6, !7, !"hello: %c"}
; CHECK: !7 = distinct !{!7, !"hello"}
; CHECK: !8 = distinct !{!8, !9, !"foo: %c"}
; CHECK: !9 = distinct !{!9, !"foo"}
; CHECK: !10 = !{!11, !12}
; CHECK: !11 = distinct !{!11, !7, !"hello: %a"}
; CHECK: !12 = distinct !{!12, !9, !"foo: %a"}
; CHECK: !13 = !{!8}
; CHECK: !14 = !{!12}
; CHECK: !15 = !{!16, !18}
; CHECK: !16 = distinct !{!16, !17, !"hello2: %a"}
; CHECK: !17 = distinct !{!17, !"hello2"}
; CHECK: !18 = distinct !{!18, !17, !"hello2: %b"}
; CHECK: !19 = !{!16}
; CHECK: !20 = !{!18}
; NO_ASSUME: !0 = !{!1}
; NO_ASSUME: !1 = distinct !{!1, !2, !"hello: %c"}
; NO_ASSUME: !2 = distinct !{!2, !"hello"}
; NO_ASSUME: !3 = !{!4}
; NO_ASSUME: !4 = distinct !{!4, !2, !"hello: %a"}
; NO_ASSUME: !5 = !{!6, !8}
; NO_ASSUME: !6 = distinct !{!6, !7, !"hello: %c"}
; NO_ASSUME: !7 = distinct !{!7, !"hello"}
; NO_ASSUME: !8 = distinct !{!8, !9, !"foo: %c"}
; NO_ASSUME: !9 = distinct !{!9, !"foo"}
; NO_ASSUME: !10 = !{!11, !12}
; NO_ASSUME: !11 = distinct !{!11, !7, !"hello: %a"}
; NO_ASSUME: !12 = distinct !{!12, !9, !"foo: %a"}
; NO_ASSUME: !13 = !{!8}
; NO_ASSUME: !14 = !{!12}
; NO_ASSUME: !15 = !{!16, !18}
; NO_ASSUME: !16 = distinct !{!16, !17, !"hello2: %a"}
; NO_ASSUME: !17 = distinct !{!17, !"hello2"}
; NO_ASSUME: !18 = distinct !{!18, !17, !"hello2: %b"}
; NO_ASSUME: !19 = !{!16}
; NO_ASSUME: !20 = !{!18}
attributes #0 = { nounwind uwtable }

View File

@ -20,6 +20,7 @@
using namespace llvm;
extern cl::opt<bool> ShouldPreserveAllAttributes;
extern cl::opt<bool> EnableKnowledgeRetention;
static void RunTest(
StringRef Head, StringRef Tail,
@ -79,6 +80,7 @@ static void AssertHasTheRightValue(CallInst *Assume, Value *WasOn,
}
TEST(AssumeQueryAPI, hasAttributeInAssume) {
EnableKnowledgeRetention.setValue(true);
StringRef Head =
"declare void @llvm.assume(i1)\n"
"declare void @func(i32*, i32*)\n"
@ -263,7 +265,8 @@ static void AssertMapHasRightValue(RetainedKnowledgeMap &Map,
}
TEST(AssumeQueryAPI, fillMapFromAssume) {
StringRef Head =
EnableKnowledgeRetention.setValue(true);
StringRef Head =
"declare void @llvm.assume(i1)\n"
"declare void @func(i32*, i32*)\n"
"declare void @func1(i32*, i32*, i32*, i32*)\n"