mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 01:29:52 +00:00
[clang] Add mustprogress and llvm.loop.mustprogress attribute deduction
Since C++11, the C++ standard has a forward progress guarantee [intro.progress], so all such functions must have the `mustprogress` requirement. In addition, from C11 and onwards, loops without a non-zero constant conditional or no conditional are also required to make progress (C11 6.8.5p6). This patch implements these attribute deductions so they can be used by the optimization passes. Differential Revision: https://reviews.llvm.org/D86841
This commit is contained in:
parent
bbd4ebffd4
commit
ac73b73c16
@ -411,10 +411,14 @@ MDNode *LoopInfo::createMetadata(
|
||||
LoopProperties.push_back(EndLoc.getAsMDNode());
|
||||
}
|
||||
|
||||
LLVMContext &Ctx = Header->getContext();
|
||||
if (Attrs.MustProgress)
|
||||
LoopProperties.push_back(
|
||||
MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.mustprogress")));
|
||||
|
||||
assert(!!AccGroup == Attrs.IsParallel &&
|
||||
"There must be an access group iff the loop is parallel");
|
||||
if (Attrs.IsParallel) {
|
||||
LLVMContext &Ctx = Header->getContext();
|
||||
LoopProperties.push_back(MDNode::get(
|
||||
Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
|
||||
}
|
||||
@ -431,7 +435,7 @@ LoopAttributes::LoopAttributes(bool IsParallel)
|
||||
VectorizePredicateEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
|
||||
InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
|
||||
DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
|
||||
PipelineInitiationInterval(0) {}
|
||||
PipelineInitiationInterval(0), MustProgress(false) {}
|
||||
|
||||
void LoopAttributes::clear() {
|
||||
IsParallel = false;
|
||||
@ -446,6 +450,7 @@ void LoopAttributes::clear() {
|
||||
DistributeEnable = LoopAttributes::Unspecified;
|
||||
PipelineDisabled = false;
|
||||
PipelineInitiationInterval = 0;
|
||||
MustProgress = false;
|
||||
}
|
||||
|
||||
LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
|
||||
@ -469,7 +474,7 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
|
||||
Attrs.UnrollEnable == LoopAttributes::Unspecified &&
|
||||
Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
|
||||
Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
|
||||
!EndLoc)
|
||||
!EndLoc && !Attrs.MustProgress)
|
||||
return;
|
||||
|
||||
TempLoopID = MDNode::getTemporary(Header->getContext(), None);
|
||||
@ -570,8 +575,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
|
||||
const clang::CodeGenOptions &CGOpts,
|
||||
ArrayRef<const clang::Attr *> Attrs,
|
||||
const llvm::DebugLoc &StartLoc,
|
||||
const llvm::DebugLoc &EndLoc) {
|
||||
|
||||
const llvm::DebugLoc &EndLoc, bool MustProgress) {
|
||||
// Identify loop hint attributes from Attrs.
|
||||
for (const auto *Attr : Attrs) {
|
||||
const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
|
||||
@ -748,6 +752,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
|
||||
}
|
||||
}
|
||||
|
||||
setMustProgress(MustProgress);
|
||||
|
||||
if (CGOpts.OptimizationLevel > 0)
|
||||
// Disable unrolling for the loop, if unrolling is disabled (via
|
||||
// -fno-unroll-loops) and no pragmas override the decision.
|
||||
|
@ -75,6 +75,9 @@ struct LoopAttributes {
|
||||
|
||||
/// Value for llvm.loop.pipeline.iicount metadata.
|
||||
unsigned PipelineInitiationInterval;
|
||||
|
||||
/// Value for whether the loop is required to make progress.
|
||||
bool MustProgress;
|
||||
};
|
||||
|
||||
/// Information used when generating a structured loop.
|
||||
@ -205,7 +208,7 @@ public:
|
||||
void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx,
|
||||
const clang::CodeGenOptions &CGOpts,
|
||||
llvm::ArrayRef<const Attr *> Attrs, const llvm::DebugLoc &StartLoc,
|
||||
const llvm::DebugLoc &EndLoc);
|
||||
const llvm::DebugLoc &EndLoc, bool MustProgress = false);
|
||||
|
||||
/// End the current loop.
|
||||
void pop();
|
||||
@ -272,6 +275,9 @@ public:
|
||||
StagedAttrs.PipelineInitiationInterval = C;
|
||||
}
|
||||
|
||||
/// Set no progress for the next loop pushed.
|
||||
void setMustProgress(bool P) { StagedAttrs.MustProgress = P; }
|
||||
|
||||
private:
|
||||
/// Returns true if there is LoopInfo on the stack.
|
||||
bool hasInfo() const { return !Active.empty(); }
|
||||
|
@ -765,11 +765,6 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
|
||||
JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
|
||||
EmitBlock(LoopHeader.getBlock());
|
||||
|
||||
const SourceRange &R = S.getSourceRange();
|
||||
LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(),
|
||||
WhileAttrs, SourceLocToDebugLoc(R.getBegin()),
|
||||
SourceLocToDebugLoc(R.getEnd()));
|
||||
|
||||
// Create an exit block for when the condition fails, which will
|
||||
// also become the break target.
|
||||
JumpDest LoopExit = getJumpDestInCurrentScope("while.end");
|
||||
@ -797,9 +792,19 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
|
||||
// while(1) is common, avoid extra exit blocks. Be sure
|
||||
// to correctly handle break/continue though.
|
||||
bool EmitBoolCondBranch = true;
|
||||
if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
|
||||
if (C->isOne())
|
||||
bool LoopMustProgress = false;
|
||||
if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) {
|
||||
if (C->isOne()) {
|
||||
EmitBoolCondBranch = false;
|
||||
FnIsMustProgress = false;
|
||||
}
|
||||
} else if (LanguageRequiresProgress())
|
||||
LoopMustProgress = true;
|
||||
|
||||
const SourceRange &R = S.getSourceRange();
|
||||
LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(),
|
||||
WhileAttrs, SourceLocToDebugLoc(R.getBegin()),
|
||||
SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
|
||||
|
||||
// As long as the condition is true, go to the loop body.
|
||||
llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
|
||||
@ -875,11 +880,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
|
||||
|
||||
EmitBlock(LoopCond.getBlock());
|
||||
|
||||
const SourceRange &R = S.getSourceRange();
|
||||
LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,
|
||||
SourceLocToDebugLoc(R.getBegin()),
|
||||
SourceLocToDebugLoc(R.getEnd()));
|
||||
|
||||
// C99 6.8.5.2: "The evaluation of the controlling expression takes place
|
||||
// after each execution of the loop body."
|
||||
|
||||
@ -893,9 +893,19 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
|
||||
// "do {} while (0)" is common in macros, avoid extra blocks. Be sure
|
||||
// to correctly handle break/continue though.
|
||||
bool EmitBoolCondBranch = true;
|
||||
if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
|
||||
bool LoopMustProgress = false;
|
||||
if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) {
|
||||
if (C->isZero())
|
||||
EmitBoolCondBranch = false;
|
||||
else if (C->isOne())
|
||||
FnIsMustProgress = false;
|
||||
} else if (LanguageRequiresProgress())
|
||||
LoopMustProgress = true;
|
||||
|
||||
const SourceRange &R = S.getSourceRange();
|
||||
LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,
|
||||
SourceLocToDebugLoc(R.getBegin()),
|
||||
SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
|
||||
|
||||
// As long as the condition is true, iterate the loop.
|
||||
if (EmitBoolCondBranch) {
|
||||
@ -933,10 +943,21 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
|
||||
llvm::BasicBlock *CondBlock = Continue.getBlock();
|
||||
EmitBlock(CondBlock);
|
||||
|
||||
bool LoopMustProgress = false;
|
||||
Expr::EvalResult Result;
|
||||
if (LanguageRequiresProgress()) {
|
||||
if (!S.getCond()) {
|
||||
LoopMustProgress = true;
|
||||
FnIsMustProgress = false;
|
||||
} else if (!S.getCond()->EvaluateAsInt(Result, getContext())) {
|
||||
LoopMustProgress = true;
|
||||
}
|
||||
}
|
||||
|
||||
const SourceRange &R = S.getSourceRange();
|
||||
LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,
|
||||
SourceLocToDebugLoc(R.getBegin()),
|
||||
SourceLocToDebugLoc(R.getEnd()));
|
||||
SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
|
||||
|
||||
// If the for loop doesn't have an increment we can just use the
|
||||
// condition as the continue block. Otherwise we'll need to create
|
||||
@ -972,6 +993,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
|
||||
llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
|
||||
llvm::MDNode *Weights = createProfileOrBranchWeightsForLoop(
|
||||
S.getCond(), getProfileCount(S.getBody()), S.getBody());
|
||||
|
||||
if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
|
||||
if (C->isOne())
|
||||
FnIsMustProgress = false;
|
||||
|
||||
Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
|
||||
|
||||
if (ExitBlock != LoopExit.getBlock()) {
|
||||
|
@ -1159,10 +1159,18 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
|
||||
|
||||
void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
|
||||
incrementProfileCounter(Body);
|
||||
if (CPlusPlusWithProgress())
|
||||
FnIsMustProgress = true;
|
||||
|
||||
if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
|
||||
EmitCompoundStmtWithoutScope(*S);
|
||||
else
|
||||
EmitStmt(Body);
|
||||
|
||||
// This is checked after emitting the function body so we know if there
|
||||
// are any permitted infinite loops.
|
||||
if (FnIsMustProgress)
|
||||
CurFn->addFnAttr(llvm::Attribute::MustProgress);
|
||||
}
|
||||
|
||||
/// When instrumenting to collect profile data, the counts for some blocks
|
||||
|
@ -502,6 +502,26 @@ public:
|
||||
/// True if the current statement has nomerge attribute.
|
||||
bool InNoMergeAttributedStmt = false;
|
||||
|
||||
/// True if the current function should be marked mustprogress.
|
||||
bool FnIsMustProgress = false;
|
||||
|
||||
/// True if the C++ Standard Requires Progress.
|
||||
bool CPlusPlusWithProgress() {
|
||||
return getLangOpts().CPlusPlus11 || getLangOpts().CPlusPlus14 ||
|
||||
getLangOpts().CPlusPlus17 || getLangOpts().CPlusPlus20;
|
||||
}
|
||||
|
||||
/// True if the C Standard Requires Progress.
|
||||
bool CWithProgress() {
|
||||
return getLangOpts().C11 || getLangOpts().C17 || getLangOpts().C2x;
|
||||
}
|
||||
|
||||
/// True if the language standard requires progress in functions or
|
||||
/// in infinite loops with non-constant conditionals.
|
||||
bool LanguageRequiresProgress() {
|
||||
return CWithProgress() || CPlusPlusWithProgress();
|
||||
}
|
||||
|
||||
const CodeGen::CGBlockInfo *BlockInfo = nullptr;
|
||||
llvm::Value *BlockPointer = nullptr;
|
||||
|
||||
|
@ -25,51 +25,51 @@
|
||||
// RUN: FileCheck -check-prefix=CHECK-KHWASAN %s
|
||||
|
||||
int HasSanitizeAddress() { return 1; }
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address
|
||||
// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address
|
||||
// CHECK-HWASAN: Function Attrs: noinline nounwind sanitize_hwaddress
|
||||
// CHECK-KHWASAN: Function Attrs: noinline nounwind sanitize_hwaddress
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address mustprogress
|
||||
// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address mustprogress
|
||||
// CHECK-HWASAN: Function Attrs: noinline nounwind sanitize_hwaddress mustprogress
|
||||
// CHECK-KHWASAN: Function Attrs: noinline nounwind sanitize_hwaddress mustprogress
|
||||
|
||||
__attribute__((no_sanitize("address"))) int NoSanitizeQuoteAddress() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
|
||||
|
||||
__attribute__((no_sanitize_address)) int NoSanitizeAddress() { return 0; }
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
|
||||
|
||||
__attribute__((no_sanitize("kernel-address"))) int NoSanitizeKernelAddress() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
|
||||
|
||||
__attribute__((no_sanitize("hwaddress"))) int NoSanitizeHWAddress() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
|
||||
__attribute__((no_sanitize("kernel-hwaddress"))) int NoSanitizeKernelHWAddress() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
|
||||
// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
|
@ -35,8 +35,7 @@ int DefinedInDifferentFile(int *a);
|
||||
// ASAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
||||
// ASAN: @__cxx_global_array_dtor{{.*}}[[WITH]]
|
||||
|
||||
|
||||
// WITHOUT: NoAddressSafety1{{.*}}) [[NOATTR]]
|
||||
// WITHOUT: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
||||
// BLFILE: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
||||
// BLFUNC: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
||||
// ASAN: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
|
||||
@ -83,8 +82,8 @@ int NoAddressSafety6(int *a) { return *a; }
|
||||
|
||||
// WITHOUT: AddressSafetyOk{{.*}}) [[NOATTR]]
|
||||
// BLFILE: AddressSafetyOk{{.*}}) [[NOATTR]]
|
||||
// BLFUNC: AddressSafetyOk{{.*}}) [[WITH]]
|
||||
// ASAN: AddressSafetyOk{{.*}}) [[WITH]]
|
||||
// BLFUNC: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
|
||||
// ASAN: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
|
||||
int AddressSafetyOk(int *a) { return *a; }
|
||||
|
||||
// WITHOUT: BlacklistedFunction{{.*}}) [[NOATTR]]
|
||||
@ -138,10 +137,10 @@ int force_instance = TemplateAddressSafetyOk<42>()
|
||||
// Check that __cxx_global_var_init* get the sanitize_address attribute.
|
||||
int global1 = 0;
|
||||
int global2 = *(int*)((char*)&global1+1);
|
||||
// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR]]
|
||||
// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
|
||||
// BLFILE: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
|
||||
// BLFUNC: @__cxx_global_var_init{{.*}}[[WITH]]
|
||||
// ASAN: @__cxx_global_var_init{{.*}}[[WITH]]
|
||||
// BLFUNC: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
||||
// ASAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
|
||||
|
||||
// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
|
||||
|
||||
|
184
clang/test/CodeGen/attr-mustprogress-0.c
Normal file
184
clang/test/CodeGen/attr-mustprogress-0.c
Normal file
@ -0,0 +1,184 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
|
||||
// RUN: %clang_cc1 -std=c89 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c99 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @f1(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f1() {
|
||||
for (; 1;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @f2(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f2() {
|
||||
for (; a == b;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @F(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: br label [[FOR_COND1:%.*]]
|
||||
// CHECK: for.cond1:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
|
||||
// CHECK: for.body2:
|
||||
// CHECK-NEXT: br label [[FOR_COND1]]
|
||||
// CHECK: for.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void F() {
|
||||
for (; 1;) {
|
||||
}
|
||||
for (; a == b;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @w1(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY]]
|
||||
//
|
||||
void w1() {
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @w2(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void w2() {
|
||||
while (a == b) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @W(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
|
||||
// CHECK: while.body2:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2]]
|
||||
//
|
||||
void W() {
|
||||
while (a == b) {
|
||||
}
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @d1(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d1() {
|
||||
do {
|
||||
} while (1);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @d2(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d2() {
|
||||
do {
|
||||
} while (a == b);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @D(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: br label [[DO_BODY1:%.*]]
|
||||
// CHECK: do.body1:
|
||||
// CHECK-NEXT: br label [[DO_COND2:%.*]]
|
||||
// CHECK: do.cond2:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]]
|
||||
// CHECK: do.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void D() {
|
||||
do {
|
||||
} while (1);
|
||||
do {
|
||||
} while (a == b);
|
||||
}
|
183
clang/test/CodeGen/attr-mustprogress-0.cpp
Normal file
183
clang/test/CodeGen/attr-mustprogress-0.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
|
||||
// RUN: %clang_cc1 -std=c++98 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2f1v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f1() {
|
||||
for (; 1;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2f2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f2() {
|
||||
for (; a == b;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z1Fv(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: br label [[FOR_COND1:%.*]]
|
||||
// CHECK: for.cond1:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
|
||||
// CHECK: for.body2:
|
||||
// CHECK-NEXT: br label [[FOR_COND1]]
|
||||
// CHECK: for.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void F() {
|
||||
for (; 1;) {
|
||||
}
|
||||
for (; a == b;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2w1v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY]]
|
||||
//
|
||||
void w1() {
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2w2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void w2() {
|
||||
while (a == b) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z1Wv(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
|
||||
// CHECK: while.body2:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2]]
|
||||
//
|
||||
void W() {
|
||||
while (a == b) {
|
||||
}
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2d1v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d1() {
|
||||
do {
|
||||
} while (1);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2d2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d2() {
|
||||
do {
|
||||
} while (a == b);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z1Dv(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: br label [[DO_BODY1:%.*]]
|
||||
// CHECK: do.body1:
|
||||
// CHECK-NEXT: br label [[DO_COND2:%.*]]
|
||||
// CHECK: do.cond2:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]]
|
||||
// CHECK: do.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void D() {
|
||||
do {
|
||||
} while (1);
|
||||
do {
|
||||
} while (a == b);
|
||||
}
|
186
clang/test/CodeGen/attr-mustprogress-1.c
Normal file
186
clang/test/CodeGen/attr-mustprogress-1.c
Normal file
@ -0,0 +1,186 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
|
||||
// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c11 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c18 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c2x -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @f1(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f1() {
|
||||
for (; 1;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @f2(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f2() {
|
||||
for (; a == b;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @F(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: br label [[FOR_COND1:%.*]]
|
||||
// CHECK: for.cond1:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
|
||||
// CHECK: for.body2:
|
||||
// CHECK-NEXT: br label [[FOR_COND1]], [[LOOP4:!llvm.loop !.*]]
|
||||
// CHECK: for.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void F() {
|
||||
for (; 1;) {
|
||||
}
|
||||
for (; a == b;) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @w1(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY]]
|
||||
//
|
||||
void w1() {
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @w2(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP5:!llvm.loop !.*]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void w2() {
|
||||
while (a == b) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @W(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP6:!llvm.loop !.*]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
|
||||
// CHECK: while.body2:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2]]
|
||||
//
|
||||
void W() {
|
||||
while (a == b) {
|
||||
}
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @d1(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d1() {
|
||||
do {
|
||||
} while (1);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @d2(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP7:!llvm.loop !.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d2() {
|
||||
do {
|
||||
} while (a == b);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @D(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: br label [[DO_BODY1:%.*]]
|
||||
// CHECK: do.body1:
|
||||
// CHECK-NEXT: br label [[DO_COND2:%.*]]
|
||||
// CHECK: do.cond2:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]], [[LOOP8:!llvm.loop !.*]]
|
||||
// CHECK: do.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void D() {
|
||||
do {
|
||||
} while (1);
|
||||
do {
|
||||
} while (a == b);
|
||||
}
|
261
clang/test/CodeGen/attr-mustprogress-1.cpp
Normal file
261
clang/test/CodeGen/attr-mustprogress-1.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
|
||||
// RUN: %clang_cc1 -std=c++11 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c++14 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c++17 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
int a = 0;
|
||||
int b = 0;
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2f1v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f1() {
|
||||
for (; 1;)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone mustprogress
|
||||
// CHECK-LABEL: @_Z2f2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void f2() {
|
||||
for (; a == b;)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z1Fv(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: br label [[FOR_COND1:%.*]]
|
||||
// CHECK: for.cond1:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
|
||||
// CHECK: for.body2:
|
||||
// CHECK-NEXT: br label [[FOR_COND1]], [[LOOP4:!llvm.loop !.*]]
|
||||
// CHECK: for.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void F() {
|
||||
for (; 1;)
|
||||
;
|
||||
for (; a == b;)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2F2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[FOR_COND:%.*]]
|
||||
// CHECK: for.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
|
||||
// CHECK: for.body:
|
||||
// CHECK-NEXT: br label [[FOR_COND]], [[LOOP5:!llvm.loop !.*]]
|
||||
// CHECK: for.end:
|
||||
// CHECK-NEXT: br label [[FOR_COND1:%.*]]
|
||||
// CHECK: for.cond1:
|
||||
// CHECK-NEXT: br i1 true, label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
|
||||
// CHECK: for.body2:
|
||||
// CHECK-NEXT: br label [[FOR_COND1]]
|
||||
// CHECK: for.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void F2() {
|
||||
for (; a == b;)
|
||||
;
|
||||
for (; 1;)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2w1v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY]]
|
||||
//
|
||||
void w1() {
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone mustprogress
|
||||
// CHECK-LABEL: @_Z2w2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP6:!llvm.loop !.*]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void w2() {
|
||||
while (a == b)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z1Wv(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_COND:%.*]]
|
||||
// CHECK: while.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP7:!llvm.loop !.*]]
|
||||
// CHECK: while.end:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
|
||||
// CHECK: while.body2:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY2]]
|
||||
//
|
||||
void W() {
|
||||
while (a == b)
|
||||
;
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2W2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
|
||||
// CHECK: while.body:
|
||||
// CHECK-NEXT: br label [[WHILE_BODY]]
|
||||
//
|
||||
void W2() {
|
||||
while (1)
|
||||
;
|
||||
while (a == b)
|
||||
;
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2d1v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d1() {
|
||||
do
|
||||
;
|
||||
while (1);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone mustprogress
|
||||
// CHECK-LABEL: @_Z2d2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP8:!llvm.loop !.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void d2() {
|
||||
do
|
||||
;
|
||||
while (a == b);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z1Dv(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: br label [[DO_BODY1:%.*]]
|
||||
// CHECK: do.body1:
|
||||
// CHECK-NEXT: br label [[DO_COND2:%.*]]
|
||||
// CHECK: do.cond2:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]], [[LOOP9:!llvm.loop !.*]]
|
||||
// CHECK: do.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void D() {
|
||||
do
|
||||
;
|
||||
while (1);
|
||||
do
|
||||
;
|
||||
while (a == b);
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK-LABEL: @_Z2D2v(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: br label [[DO_BODY:%.*]]
|
||||
// CHECK: do.body:
|
||||
// CHECK-NEXT: br label [[DO_COND:%.*]]
|
||||
// CHECK: do.cond:
|
||||
// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
|
||||
// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
|
||||
// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
|
||||
// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP10:!llvm.loop !.*]]
|
||||
// CHECK: do.end:
|
||||
// CHECK-NEXT: br label [[DO_BODY1:%.*]]
|
||||
// CHECK: do.body1:
|
||||
// CHECK-NEXT: br label [[DO_COND2:%.*]]
|
||||
// CHECK: do.cond2:
|
||||
// CHECK-NEXT: br i1 true, label [[DO_BODY1]], label [[DO_END3:%.*]]
|
||||
// CHECK: do.end3:
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
void D2() {
|
||||
do
|
||||
;
|
||||
while (a == b);
|
||||
do
|
||||
;
|
||||
while (1);
|
||||
}
|
||||
|
@ -9,11 +9,11 @@
|
||||
// RUN: FileCheck -check-prefix=CHECK-MEMTAG %s
|
||||
|
||||
int HasSanitizeMemTag() { return 1; }
|
||||
// CHECK-NO: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-NO: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-MEMTAG: Function Attrs: noinline nounwind sanitize_memtag
|
||||
|
||||
__attribute__((no_sanitize("memtag"))) int NoSanitizeQuoteAddress() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NO: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-MEMTAG: {{Function Attrs: noinline nounwind$}}
|
||||
// CHECK-NO: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
// CHECK-MEMTAG: {{Function Attrs: noinline nounwind mustprogress$}}
|
||||
|
@ -43,7 +43,7 @@ extern "C" void call_b_foo(B *b) {
|
||||
|
||||
// CHECK-LABEL: define void @call_foo_no_mempcy() #3
|
||||
extern "C" void call_foo_no_mempcy() {
|
||||
// CHECK: call void @foo_no_mempcy() #6
|
||||
// CHECK: call void @foo_no_mempcy() #7
|
||||
foo_no_mempcy(); // call gets annotated with "no-builtin-memcpy"
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ A::~A() {} // Anchoring A so A::foo() gets generated
|
||||
B::~B() {} // Anchoring B so B::foo() gets generated
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr i32 @_ZNK1A3fooEv(%struct.A* %this) unnamed_addr #0 comdat align 2
|
||||
// CHECK-LABEL: define linkonce_odr i32 @_ZNK1B3fooEv(%struct.B* %this) unnamed_addr #5 comdat align 2
|
||||
// CHECK-LABEL: define linkonce_odr i32 @_ZNK1B3fooEv(%struct.B* %this) unnamed_addr #6 comdat align 2
|
||||
|
||||
// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
|
||||
// CHECK-NOT: attributes #0 = {{{.*}}"no-builtin-memmove"{{.*}}}
|
||||
@ -59,7 +59,7 @@ B::~B() {} // Anchoring B so B::foo() gets generated
|
||||
// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
|
||||
// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
|
||||
// CHECK-NOT: attributes #2 = {{{.*}}"no-builtin-memmove"{{.*}}}
|
||||
// CHECK: attributes #5 = {{{.*}}"no-builtin-memmove"{{.*}}}
|
||||
// CHECK: attributes #6 = {{{.*}}"no-builtin-memmove"{{.*}}}
|
||||
// CHECK-NOT: attributes #5 = {{{.*}}"no-builtin-memcpy"{{.*}}}
|
||||
// CHECK-NOT: attributes #5 = {{{.*}}"no-builtin-memset"{{.*}}}
|
||||
// CHECK: attributes #6 = { "no-builtin-memcpy" }
|
||||
// CHECK: attributes #7 = { "no-builtin-memcpy" }
|
||||
|
@ -17,8 +17,9 @@
|
||||
// CHECK: br {{.*}}, label %do.body, label %do.end, !llvm.loop ![[LMD1:[0-9]+]]
|
||||
// CHECK-LABEL: do.end:
|
||||
// CHECK-NOT: llvm.loop
|
||||
// CHECK: ![[LMD1]] = distinct !{![[LMD1]], ![[LMD2:[0-9]+]]}
|
||||
// CHECK: ![[LMD2]] = !{!"llvm.loop.unroll.count", i32 4}
|
||||
// CHECK: ![[LMD1]] = distinct !{![[LMD1]], [[LMD2:![0-9]+]], ![[LMD3:[0-9]+]]}
|
||||
// CHECK: [[LMD2]] = !{!"llvm.loop.mustprogress"}
|
||||
// CHECK: ![[LMD3]] = !{!"llvm.loop.unroll.count", i32 4}
|
||||
|
||||
int test(int a[], int n) {
|
||||
int i = 0;
|
||||
|
@ -9,7 +9,7 @@ void wl(int e){
|
||||
|
||||
void wu(int e){
|
||||
// CHECK-LABEL: define{{.*}}wu
|
||||
// CHECK: br {{.*}} !prof !9
|
||||
// CHECK: br {{.*}} !prof !10
|
||||
while(e) [[unlikely]] ++e;
|
||||
}
|
||||
|
||||
@ -31,7 +31,7 @@ void fl(unsigned e)
|
||||
void fu(int e)
|
||||
{
|
||||
// CHECK-LABEL: define{{.*}}fu
|
||||
// CHECK: br {{.*}} !prof !9
|
||||
// CHECK: br {{.*}} !prof !10
|
||||
for(int i = 0; i != e; ++e) [[unlikely]];
|
||||
}
|
||||
|
||||
@ -52,9 +52,9 @@ void frl(int (&&e) [4])
|
||||
void fru(int (&&e) [4])
|
||||
{
|
||||
// CHECK-LABEL: define{{.*}}fru
|
||||
// CHECK: br {{.*}} !prof !9
|
||||
// CHECK: br {{.*}} !prof !10
|
||||
for(int i : e) [[unlikely]];
|
||||
}
|
||||
|
||||
// CHECK: !6 = !{!"branch_weights", i32 2000, i32 1}
|
||||
// CHECK: !9 = !{!"branch_weights", i32 1, i32 2000}
|
||||
// CHECK: !10 = !{!"branch_weights", i32 1, i32 2000}
|
||||
|
@ -1,7 +1,11 @@
|
||||
// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o %t-c++11.ll %s -triple x86_64-apple-darwin10
|
||||
// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o %t-c++11.ll %s -triple x86_64-apple-darwin10
|
||||
// RUN: FileCheck %s < %t-c++11.ll
|
||||
// RUN: %clang_cc1 -std=c++98 -S -emit-llvm -o %t.ll %s -triple x86_64-apple-darwin10
|
||||
// RUN: diff %t.ll %t-c++11.ll
|
||||
// RUN: %clang_cc1 -std=c++17 -S -emit-llvm -o %t-c++17.ll %s -triple x86_64-apple-darwin10
|
||||
// RUN: FileCheck %s < %t-c++17.ll
|
||||
// RUN: %clang_cc1 -std=c++98 -S -emit-llvm -o %t.ll %s -triple x86_64-apple-darwin10
|
||||
// RUN: %clang_cc1 -std=c++03 -S -emit-llvm -o %t-c++03.ll %s -triple x86_64-apple-darwin10
|
||||
// RUN: diff %t-c++11.ll %t-c++17.ll
|
||||
// RUN: diff %t.ll %t-c++03.ll
|
||||
|
||||
// rdar://12897704
|
||||
|
||||
|
@ -57,11 +57,11 @@ int main() {
|
||||
// CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, scope: !{{.*}})
|
||||
// CHECK-DAG: [[ELDBG1]] = !DILocation(line: 104, scope: !{{.*}})
|
||||
|
||||
// CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
|
||||
// CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]], [[MP:![0-9]+]]}
|
||||
// CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, scope: !{{.*}})
|
||||
// CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, scope: !{{.*}})
|
||||
|
||||
// CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
|
||||
// CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]], [[MP]]}
|
||||
// CHECK-DAG: [[SLDBG3]] = !DILocation(line: 300, scope: !{{.*}})
|
||||
// CHECK-DAG: [[ELDBG3]] = !DILocation(line: 304, scope: !{{.*}})
|
||||
|
||||
|
@ -35,7 +35,7 @@ int main() {
|
||||
// CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, column: 3, scope: !{{.*}})
|
||||
// CHECK-DAG: [[ELDBG1]] = !DILocation(line: 105, column: 3, scope: !{{.*}})
|
||||
|
||||
// CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
|
||||
// CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]], [[MP:![0-9]+]]}
|
||||
// CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, column: 3, scope: !{{.*}})
|
||||
// CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, column: 9, scope: !{{.*}})
|
||||
|
||||
@ -43,7 +43,7 @@ int main() {
|
||||
// CHECK-DAG: [[SLDBG3]] = !DILocation(line: 302, column: 5, scope: !{{.*}})
|
||||
// CHECK-DAG: [[ELDBG3]] = !DILocation(line: 303, column: 9, scope: !{{.*}})
|
||||
//
|
||||
// CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
|
||||
// CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]], [[MP]]}
|
||||
// CHECK-DAG: [[SLDBG4]] = !DILocation(line: 300, column: 3, scope: !{{.*}})
|
||||
// CHECK-DAG: [[ELDBG4]] = !DILocation(line: 304, column: 3, scope: !{{.*}})
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s -O3 -disable-llvm-optzns -fno-unroll-loops | FileCheck --check-prefix=UNROLL_DISABLED_MD %s
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s -O3 -disable-llvm-optzns | FileCheck --check-prefix=NO_UNROLL_MD %s
|
||||
|
||||
// NO_UNROLL_MD-NOT: llvm.loop
|
||||
// NO_UNROLL_MD-NOT: llvm.loop.unroll.disable
|
||||
|
||||
// Verify unroll.disable metadata is added to while loop with -fno-unroll-loops
|
||||
// and optlevel > 0.
|
||||
@ -13,7 +13,7 @@ void while_test(int *List, int Length) {
|
||||
int i = 0;
|
||||
|
||||
while (i < Length) {
|
||||
// UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
|
||||
// UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop [[LOOP_1:![0-9]+]]
|
||||
List[i] = i * 2;
|
||||
i++;
|
||||
}
|
||||
@ -26,7 +26,7 @@ void do_test(int *List, int Length) {
|
||||
int i = 0;
|
||||
|
||||
do {
|
||||
// UNROLL_DISABLED_MD: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
|
||||
// UNROLL_DISABLED_MD: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop [[LOOP_2:![0-9]+]]
|
||||
List[i] = i * 2;
|
||||
i++;
|
||||
} while (i < Length);
|
||||
@ -37,12 +37,13 @@ void do_test(int *List, int Length) {
|
||||
void for_test(int *List, int Length) {
|
||||
// UNROLL_DISABLED_MD: define {{.*}} @_Z8for_test
|
||||
for (int i = 0; i < Length; i++) {
|
||||
// UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
|
||||
// UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop [[LOOP_3:![0-9]+]]
|
||||
List[i] = i * 2;
|
||||
}
|
||||
}
|
||||
|
||||
// UNROLL_DISABLED_MD: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_DISABLE:.*]]}
|
||||
// UNROLL_DISABLED_MD: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
|
||||
// UNROLL_DISABLED_MD: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[UNROLL_DISABLE:.*]]}
|
||||
// UNROLL_DISABLED_MD: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_DISABLE:.*]]}
|
||||
// UNROLL_DISABLED_MD: [[LOOP_1]] = distinct !{[[LOOP_1]], [[MP:![0-9]+]], [[UNROLL_DISABLE:![0-9]+]]}
|
||||
// UNROLL_DISABLED_MD: [[MP]] = !{!"llvm.loop.mustprogress"}
|
||||
// UNROLL_DISABLED_MD: [[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
|
||||
// UNROLL_DISABLED_MD: [[LOOP_2]] = distinct !{[[LOOP_2]], [[MP]], [[UNROLL_DISABLE]]}
|
||||
// UNROLL_DISABLED_MD: [[LOOP_3]] = distinct !{[[LOOP_3]], [[MP]], [[UNROLL_DISABLE]]}
|
||||
|
@ -28,9 +28,9 @@ extern "C" void followup_inner(int n, int *x) {
|
||||
// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]]}
|
||||
// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
|
||||
|
||||
// CHECK-DAG: ![[OUTERLOOP_9:[0-9]+]] = distinct !{![[OUTERLOOP_9:[0-9]+]], ![[UNROLLANDJAM_COUNT_10:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]]}
|
||||
// CHECK-DAG: ![[OUTERLOOP_9:[0-9]+]] = distinct !{![[OUTERLOOP_9:[0-9]+]], [[MP:![0-9]+]], ![[UNROLLANDJAM_COUNT_10:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]]}
|
||||
// CHECK-DAG: ![[UNROLLANDJAM_COUNT_10:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
|
||||
// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_inner", !12}
|
||||
// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_inner", !13}
|
||||
|
||||
// CHECK-DAG: ![[LOOP_12:[0-9]+]] = distinct !{![[LOOP_12:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_13:[0-9]+]], ![[UNROLL_COUNT_13:[0-9]+]], ![[UNROLL_FOLLOWUP_14:[0-9]+]]}
|
||||
// CHECK-DAG: ![[ISVECTORIZED_13:[0-9]+]] = !{!"llvm.loop.isvectorized"}
|
||||
|
@ -17,25 +17,25 @@ extern "C" void followup_outer(int n, int *x) {
|
||||
|
||||
// CHECK-DAG: ![[ACCESSGROUP_2:[0-9]+]] = distinct !{}
|
||||
|
||||
// CHECK-DAG: ![[LOOP_3:[0-9]+]] = distinct !{![[LOOP_3:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
|
||||
// CHECK-DAG: ![[LOOP_3:[0-9]+]] = distinct !{![[LOOP_3:[0-9]+]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
|
||||
// CHECK-DAG: ![[PARALLEL_ACCESSES_4:[0-9]+]] = !{!"llvm.loop.parallel_accesses", ![[ACCESSGROUP_2]]}
|
||||
// CHECK-DAG: ![[DISTRIBUTE_5:[0-9]+]] = !{!"llvm.loop.distribute.enable", i1 true}
|
||||
// CHECK-DAG: ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]] = !{!"llvm.loop.distribute.followup_all", ![[LOOP_7:[0-9]+]]}
|
||||
|
||||
// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]], ![[VECTORIZE_FOLLOWUP_9:[0-9]+]]}
|
||||
// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]], ![[VECTORIZE_FOLLOWUP_9:[0-9]+]]}
|
||||
// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
|
||||
// CHECK-DAG: ![[VECTORIZE_FOLLOWUP_9:[0-9]+]] = !{!"llvm.loop.vectorize.followup_all", ![[LOOP_10:[0-9]+]]}
|
||||
|
||||
// CHECK-DAG: ![[LOOP_10:[0-9]+]] = distinct !{![[LOOP_10:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_12:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]]}
|
||||
// CHECK-DAG: ![[LOOP_10:[0-9]+]] = distinct !{![[LOOP_10:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_12:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]]}
|
||||
// CHECK-DAG: ![[ISVECTORIZED_11:[0-9]+]] = !{!"llvm.loop.isvectorized"}
|
||||
// CHECK-DAG: ![[UNROLLANDJAM_12:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.enable"}
|
||||
// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[LOOP_14:[0-9]+]]}
|
||||
|
||||
// CHECK-DAG: ![[LOOP_14:[0-9]+]] = distinct !{![[LOOP_14:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_COUNT_16:[0-9]+]], ![[UNROLL_FOLLOWUP_17:[0-9]+]]}
|
||||
// CHECK-DAG: ![[LOOP_14:[0-9]+]] = distinct !{![[LOOP_14:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_COUNT_16:[0-9]+]], ![[UNROLL_FOLLOWUP_17:[0-9]+]]}
|
||||
// CHECK-DAG: ![[UNROLLANDJAM_DISABLE_15:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.disable"}
|
||||
// CHECK-DAG: ![[UNROLL_COUNT_16:[0-9]+]] = !{!"llvm.loop.unroll.count", i32 4}
|
||||
// CHECK-DAG: ![[UNROLL_FOLLOWUP_17:[0-9]+]] = !{!"llvm.loop.unroll.followup_all", ![[LOOP_18:[0-9]+]]}
|
||||
|
||||
// CHECK-DAG: ![[LOOP_18:[0-9]+]] = distinct !{![[LOOP_18:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_DISABLE_19:[0-9]+]], ![[INITIATIONINTERVAL_20:[0-9]+]]}
|
||||
// CHECK-DAG: ![[LOOP_18:[0-9]+]] = distinct !{![[LOOP_18:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_DISABLE_19:[0-9]+]], ![[INITIATIONINTERVAL_20:[0-9]+]]}
|
||||
// CHECK-DAG: ![[UNROLL_DISABLE_19:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
|
||||
// CHECK-DAG: ![[INITIATIONINTERVAL_20:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
|
||||
|
@ -13,11 +13,12 @@ void while_test(int *List, int Length, int *List2, int Length2) {
|
||||
|
||||
i = 0;
|
||||
while (i < Length2) {
|
||||
// CHECK-NOT: br label {{.*}}, !llvm.loop
|
||||
// CHECK: br label {{.*}}, !llvm.loop [[LOOP_2:![0-9]+]]
|
||||
List2[i] = i * 2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[DISTRIBUTE_ENABLE:.*]]}
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[DISTRIBUTE_ENABLE:.*]]}
|
||||
// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
|
||||
// CHECK: [[LOOP_2]] = distinct !{[[LOOP_2]], [[MP]]}
|
||||
|
@ -40,13 +40,13 @@ void loop4(int *List, int Length) {
|
||||
List[i] = i * 2;
|
||||
}
|
||||
|
||||
// CHECK: ![[LOOP1]] = distinct !{![[LOOP1]], ![[VEC_WIDTH_1:.*]], ![[VEC_ENABLE:.*]]}
|
||||
// CHECK: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP:![0-9]+]], ![[VEC_WIDTH_1:.*]], ![[VEC_ENABLE:.*]]}
|
||||
// CHECK: ![[VEC_WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
|
||||
// CHECK: ![[VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true}
|
||||
|
||||
// CHECK: ![[LOOP2]] = distinct !{![[LOOP2]], ![[VEC_WIDTH_2:.*]], ![[VEC_ENABLE]]}
|
||||
// CHECK: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], ![[VEC_WIDTH_2:.*]], ![[VEC_ENABLE]]}
|
||||
// CHECK: ![[VEC_WIDTH_2]] = !{!"llvm.loop.vectorize.width", i32 2}
|
||||
|
||||
// CHECK: ![[LOOP3]] = distinct !{![[LOOP3]], ![[VEC_WIDTH_1]]}
|
||||
// CHECK: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], ![[VEC_WIDTH_1]]}
|
||||
|
||||
// CHECK: ![[LOOP4]] = distinct !{![[LOOP4]], ![[VEC_WIDTH_2]], ![[VEC_ENABLE]]}
|
||||
// CHECK: ![[LOOP4]] = distinct !{![[LOOP4]], [[MP]], ![[VEC_WIDTH_2]], ![[VEC_ENABLE]]}
|
||||
|
@ -58,19 +58,19 @@ void test5(int *List, int Length) {
|
||||
List[i] = i * 2;
|
||||
}
|
||||
|
||||
// CHECK: ![[LOOP0]] = distinct !{![[LOOP0]], [[MP:![0-9]+]], [[GEN3:![0-9]+]]}
|
||||
// CHECK: [[MP]] = !{!"llvm.loop.mustprogress"}
|
||||
// CHECK-NEXT: [[GEN3]] = !{!"llvm.loop.vectorize.enable", i1 true}
|
||||
|
||||
// CHECK: ![[LOOP0]] = distinct !{![[LOOP0]], !3}
|
||||
// CHECK-NEXT: !3 = !{!"llvm.loop.vectorize.enable", i1 true}
|
||||
// CHECK-NEXT: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP]], [[GEN6:![0-9]+]], [[GEN3]]}
|
||||
// CHECK-NEXT: [[GEN6]] = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
|
||||
|
||||
// CHECK-NEXT: ![[LOOP1]] = distinct !{![[LOOP1]], !5, !3}
|
||||
// CHECK-NEXT: !5 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
|
||||
// CHECK-NEXT: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], [[GEN8:![0-9]+]], [[GEN3]]}
|
||||
// CHECK-NEXT: [[GEN8]] = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
|
||||
|
||||
// CHECK-NEXT: ![[LOOP2]] = distinct !{![[LOOP2]], !7, !3}
|
||||
// CHECK-NEXT: !7 = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
|
||||
// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], [[GEN6]], [[GEN3]]}
|
||||
|
||||
// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], !5, !3}
|
||||
// CHECK-NEXT: ![[LOOP4]] = distinct !{![[LOOP4]], [[MP]], [[GEN10:![0-9]+]]}
|
||||
// CHECK-NEXT: [[GEN10]] = !{!"llvm.loop.vectorize.width", i32 1}
|
||||
|
||||
// CHECK-NEXT: ![[LOOP4]] = distinct !{![[LOOP4]], !10}
|
||||
// CHECK-NEXT: !10 = !{!"llvm.loop.vectorize.width", i32 1}
|
||||
|
||||
// CHECK-NEXT: ![[LOOP5]] = distinct !{![[LOOP5]], !10}
|
||||
// CHECK-NEXT: ![[LOOP5]] = distinct !{![[LOOP5]], [[MP]], [[GEN10]]}
|
||||
|
@ -26,7 +26,8 @@ void vectorize_imperfectly_nested_test(int *List, int Length) {
|
||||
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
|
||||
// CHECK: ![[ACCESS_GROUP_LIST_3:[0-9]+]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
|
||||
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
|
||||
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
|
||||
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
|
||||
// CHECK: [[MP]] = !{!"llvm.loop.mustprogress"}
|
||||
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
|
||||
// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
|
||||
// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], [[MP]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
|
||||
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
|
||||
|
@ -21,7 +21,7 @@ void vectorize_nested_test(int *List, int Length) {
|
||||
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
|
||||
// CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
|
||||
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
|
||||
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
|
||||
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
|
||||
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
|
||||
// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
|
||||
// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], [[MP]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
|
||||
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
|
||||
|
@ -18,5 +18,5 @@ void vectorize_outer_test(int *List, int Length) {
|
||||
|
||||
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
|
||||
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
|
||||
// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_9:[0-9]+]]
|
||||
// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_9:[0-9]+]]
|
||||
// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
|
||||
|
@ -47,12 +47,12 @@ void interleave_test(int *List, int Length) {
|
||||
}
|
||||
|
||||
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
|
||||
// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[PARALLEL_ACCESSES_7:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]]}
|
||||
// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_7:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]]}
|
||||
// CHECK: ![[PARALLEL_ACCESSES_7]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
|
||||
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
|
||||
// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
|
||||
// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
|
||||
// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
|
||||
// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]]}
|
||||
// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], [[MP]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]]}
|
||||
// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
|
||||
// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
|
||||
|
@ -158,10 +158,10 @@ void template_test(double *List, int Length) {
|
||||
for_template_constant_expression_test<double, 2, 4, 8>(List, Length);
|
||||
}
|
||||
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_FULL:.*]]}
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[UNROLL_FULL:.*]]}
|
||||
// CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
|
||||
|
||||
// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[VECTORIZE_ENABLE:.*]]}
|
||||
// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], [[MP]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[VECTORIZE_ENABLE:.*]]}
|
||||
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
|
||||
// CHECK: ![[DISTRIBUTE_DISABLE]] = !{!"llvm.loop.distribute.enable", i1 false}
|
||||
// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
|
||||
@ -170,7 +170,7 @@ void template_test(double *List, int Length) {
|
||||
|
||||
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[VECTORIZE_ENABLE]], ![[FOLLOWUP_VECTOR_3:.*]]}
|
||||
// CHECK: ![[FOLLOWUP_VECTOR_3]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_3:.*]]}
|
||||
// CHECK: ![[AFTER_VECTOR_3]] = distinct !{![[AFTER_VECTOR_3]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
|
||||
// CHECK: ![[AFTER_VECTOR_3]] = distinct !{![[AFTER_VECTOR_3]], [[MP]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
|
||||
// CHECK: ![[ISVECTORIZED]] = !{!"llvm.loop.isvectorized"}
|
||||
// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
|
||||
|
||||
@ -185,7 +185,7 @@ void template_test(double *List, int Length) {
|
||||
// CHECK: ![[FOLLOWUP_VECTOR_6]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_6:.*]]}
|
||||
// CHECK: ![[AFTER_VECTOR_6]] = distinct !{![[AFTER_VECTOR_6]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
|
||||
|
||||
// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[WIDTH_5:.*]], ![[VECTORIZE_ENABLE]]}
|
||||
// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], [[MP]], ![[WIDTH_5:.*]], ![[VECTORIZE_ENABLE]]}
|
||||
// CHECK: ![[WIDTH_5]] = !{!"llvm.loop.vectorize.width", i32 5}
|
||||
|
||||
// CHECK: ![[LOOP_8]] = distinct !{![[LOOP_8]], ![[WIDTH_5:.*]]}
|
||||
@ -213,5 +213,5 @@ void template_test(double *List, int Length) {
|
||||
// CHECK: ![[AFTER_VECTOR_13]] = distinct !{![[AFTER_VECTOR_13]], ![[ISVECTORIZED:.*]], ![[UNROLL_32:.*]]}
|
||||
// CHECK: ![[UNROLL_32]] = !{!"llvm.loop.unroll.count", i32 32}
|
||||
|
||||
// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], ![[WIDTH_10:.*]], ![[VECTORIZE_ENABLE]]}
|
||||
// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], [[MP]], ![[WIDTH_10:.*]], ![[VECTORIZE_ENABLE]]}
|
||||
// CHECK: ![[WIDTH_10]] = !{!"llvm.loop.vectorize.width", i32 10}
|
||||
|
@ -36,12 +36,12 @@ void pipeline_disabled_on_nested_loop(int *List, int Length, int Value) {
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[PIPELINE_DISABLE:.*]]}
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[PIPELINE_DISABLE:.*]]}
|
||||
// CHECK: ![[PIPELINE_DISABLE]] = !{!"llvm.loop.pipeline.disable", i1 true}
|
||||
|
||||
// CHECK-NOT:llvm.loop.pipeline
|
||||
|
||||
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[PIPELINE_II_10:.*]]}
|
||||
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], [[MP]], ![[PIPELINE_II_10:.*]]}
|
||||
// CHECK: ![[PIPELINE_II_10]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
|
||||
|
||||
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[PIPELINE_DISABLE]]}
|
||||
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], [[MP]], ![[PIPELINE_DISABLE]]}
|
||||
|
@ -6,6 +6,7 @@ void unroll_and_jam(int *List, int Length, int Value) {
|
||||
for (int i = 0; i < Length; i++) {
|
||||
for (int j = 0; j < Length; j++) {
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
|
||||
List[i * Length + j] = Value;
|
||||
}
|
||||
}
|
||||
@ -16,7 +17,8 @@ void unroll_and_jam_count(int *List, int Length, int Value) {
|
||||
#pragma unroll_and_jam(4)
|
||||
for (int i = 0; i < Length; i++) {
|
||||
for (int j = 0; j < Length; j++) {
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
|
||||
List[i * Length + j] = Value;
|
||||
}
|
||||
}
|
||||
@ -27,7 +29,8 @@ void nounroll_and_jam(int *List, int Length, int Value) {
|
||||
#pragma nounroll_and_jam
|
||||
for (int i = 0; i < Length; i++) {
|
||||
for (int j = 0; j < Length; j++) {
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
|
||||
List[i * Length + j] = Value;
|
||||
}
|
||||
}
|
||||
@ -40,16 +43,17 @@ void clang_unroll_plus_nounroll_and_jam(int *List, int Length, int Value) {
|
||||
for (int i = 0; i < Length; i++) {
|
||||
for (int j = 0; j < Length; j++) {
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
|
||||
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_8:.*]]
|
||||
List[i * Length + j] = Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNJ_ENABLE:.*]]}
|
||||
// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], [[MP:![0-9]+]], ![[UNJ_ENABLE:.*]]}
|
||||
// CHECK: ![[UNJ_ENABLE]] = !{!"llvm.loop.unroll_and_jam.enable"}
|
||||
// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNJ_4:.*]]}
|
||||
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], [[MP]], ![[UNJ_4:.*]]}
|
||||
// CHECK: ![[UNJ_4]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
|
||||
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNJ_DISABLE:.*]]}
|
||||
// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], [[MP]], ![[UNJ_DISABLE:.*]]}
|
||||
// CHECK: ![[UNJ_DISABLE]] = !{!"llvm.loop.unroll_and_jam.disable"}
|
||||
// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNJ_DISABLE:.*]], ![[UNROLL_4:.*]]}
|
||||
// CHECK: ![[LOOP_8]] = distinct !{![[LOOP_8]], [[MP]], ![[UNJ_DISABLE:.*]], ![[UNROLL_4:.*]]}
|
||||
// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
|
||||
|
@ -96,11 +96,11 @@ void template_test(double *List, int Length) {
|
||||
for_template_define_test<double>(List, Length, Value);
|
||||
}
|
||||
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_ENABLE:.*]]}
|
||||
// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[UNROLL_ENABLE:.*]]}
|
||||
// CHECK: ![[UNROLL_ENABLE]] = !{!"llvm.loop.unroll.enable"}
|
||||
// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[UNROLL_DISABLE:.*]]}
|
||||
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
|
||||
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_8:.*]]}
|
||||
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], [[MP]], ![[UNROLL_8:.*]]}
|
||||
// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
|
||||
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[UNROLL_4:.*]]}
|
||||
// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
|
||||
|
@ -17,13 +17,13 @@ class C : A, B {
|
||||
};
|
||||
void C::primary_key() {}
|
||||
|
||||
// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this)
|
||||
// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this) {{.*}} #2
|
||||
// CHECK-NOT: invoke
|
||||
// CHECK: tail call void @_ZN1C9secondaryEv(%class.C* %{{.*}})
|
||||
// CHECK-NOT: invoke
|
||||
// CHECK: ret void
|
||||
|
||||
// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...)
|
||||
// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...) {{.*}} #2
|
||||
// CHECK-NOT: invoke
|
||||
// CHECK: musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* %{{.*}}, i32 %{{.*}}, ...) #2
|
||||
// CHECK: musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* %{{.*}}, i32 %{{.*}}, ...) #3
|
||||
// CHECK-NEXT: ret void
|
||||
|
@ -529,7 +529,7 @@ C c;
|
||||
// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
|
||||
|
||||
// Checking with opt
|
||||
// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #0 align 2
|
||||
// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #1 align 2
|
||||
|
||||
// This is from Test5:
|
||||
// CHECK-OPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
|
||||
|
@ -110,7 +110,8 @@ void h3(float *c, float *a, float *b, int size)
|
||||
}
|
||||
// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_13:[0-9]+]]
|
||||
}
|
||||
// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
|
||||
// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER_INNER:![0-9]+]]
|
||||
// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
|
||||
}
|
||||
|
||||
// Metadata for h1:
|
||||
|
@ -16,7 +16,7 @@ int never_called(int i) {
|
||||
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
|
||||
while (--i) {}
|
||||
|
||||
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
|
||||
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP1:!.*]]
|
||||
do {} while (i++ < 75);
|
||||
|
||||
// PGOUSE: switch {{.*}} [
|
||||
@ -46,7 +46,7 @@ int dead_code(int i) {
|
||||
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
|
||||
while (--i) {}
|
||||
|
||||
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
|
||||
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP2:!.*]]
|
||||
do {} while (i++ < 75);
|
||||
|
||||
// PGOUSE: switch {{.*}} [
|
||||
|
@ -44,7 +44,7 @@ Foo::Foo(int x) : x(x) {}
|
||||
// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca %class.Foo*, align 8
|
||||
// CHECK-NEXT: store %class.Foo* [[THIS:%.*]], %class.Foo** [[THIS_ADDR]], align 8
|
||||
// CHECK-NEXT: [[THIS1:%.*]] = load %class.Foo*, %class.Foo** [[THIS_ADDR]], align 8
|
||||
// CHECK-NEXT: call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR2:#.*]]
|
||||
// CHECK-NEXT: call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR3:#.*]]
|
||||
// CHECK-NEXT: ret void
|
||||
//
|
||||
Foo::~Foo() {}
|
||||
@ -70,7 +70,7 @@ int Foo::function_defined_out_of_line(int arg) const { return x - arg; }
|
||||
// CHECK-NEXT: call void @_ZN3FooC1Ei(%class.Foo* [[F]], i32 1)
|
||||
// CHECK-NEXT: [[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* [[F]], i32 2)
|
||||
// CHECK-NEXT: [[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* [[F]], i32 3)
|
||||
// CHECK-NEXT: call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR2]]
|
||||
// CHECK-NEXT: call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR3]]
|
||||
// CHECK-NEXT: ret i32 0
|
||||
//
|
||||
int main() {
|
||||
|
@ -11,7 +11,7 @@ struct ST {
|
||||
struct RT Z;
|
||||
};
|
||||
|
||||
// CHECK: Function Attrs: noinline nounwind optnone
|
||||
// CHECK: Function Attrs: noinline nounwind optnone mustprogress
|
||||
// CHECK-LABEL: @_Z3fooP2ST(
|
||||
// CHECK-NEXT: entry:
|
||||
// CHECK-NEXT: [[S_ADDR:%.*]] = alloca %struct.ST*, align 8
|
||||
|
@ -197,7 +197,7 @@ void foo(void) {
|
||||
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
|
||||
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
|
||||
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
|
||||
// NOOMP-NEXT: br label [[FOR_COND]]
|
||||
// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
|
||||
// NOOMP: for.end:
|
||||
// NOOMP-NEXT: call void @foo()
|
||||
// NOOMP-NEXT: ret i32 0
|
||||
@ -223,7 +223,7 @@ void foo(void) {
|
||||
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
|
||||
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
|
||||
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
|
||||
// NOOMP-NEXT: br label [[FOR_COND]]
|
||||
// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]]
|
||||
// NOOMP: for.end:
|
||||
// NOOMP-NEXT: ret void
|
||||
//
|
||||
|
@ -41,7 +41,7 @@ void foo(void);
|
||||
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
|
||||
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
|
||||
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
|
||||
// NOOMP-NEXT: br label [[FOR_COND]]
|
||||
// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
|
||||
// NOOMP: for.end:
|
||||
// NOOMP-NEXT: call void @foo()
|
||||
// NOOMP-NEXT: ret i32 0
|
||||
@ -86,7 +86,7 @@ int main() {
|
||||
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
|
||||
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
|
||||
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
|
||||
// NOOMP-NEXT: br label [[FOR_COND]]
|
||||
// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]]
|
||||
// NOOMP: for.end:
|
||||
// NOOMP-NEXT: ret void
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user