summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2018-12-18 22:54:03 +0000
committerBill Wendling <isanbard@gmail.com>2018-12-18 22:54:03 +0000
commitaa77513bb99775fb44eddea9ace0d45a55aaf802 (patch)
tree56d5b393aae357dfc3f81b59ad82350eb141c293
parentbb3d3a8f2ed5af0c080970ec8f3bcb39303f6566 (diff)
downloadbcm5719-llvm-aa77513bb99775fb44eddea9ace0d45a55aaf802.tar.gz
bcm5719-llvm-aa77513bb99775fb44eddea9ace0d45a55aaf802.zip
Emit ASM input in a constant context
Summary: Some ASM input constraints (e.g., "i" and "n") require immediate values. At O0, very few code transformations are performed. So if we cannot resolve to an immediate when emitting the ASM input we shouldn't delay its processing. Reviewers: rsmith, efriedma Reviewed By: efriedma Subscribers: rehana, efriedma, craig.topper, jyknight, cfe-commits Differential Revision: https://reviews.llvm.org/D55616 llvm-svn: 349561
-rw-r--r--clang/lib/Basic/TargetInfo.cpp2
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp7
-rw-r--r--clang/lib/Sema/SemaStmtAsm.cpp16
-rw-r--r--clang/test/CodeGen/builtin-constant-p.c11
4 files changed, 26 insertions, 10 deletions
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 7b69cb097c8..269fad38b8d 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -685,7 +685,9 @@ bool TargetInfo::validateInputConstraint(
// FIXME: Fail if % is used with the last operand.
break;
case 'i': // immediate integer.
+ break;
case 'n': // immediate integer with a known value.
+ Info.setRequiresImmediate();
break;
case 'I': // Various constant constraints with target-specific meanings.
case 'J':
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index bc7a18af1e5..0242b48659d 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1820,11 +1820,14 @@ llvm::Value* CodeGenFunction::EmitAsmInput(
// If this can't be a register or memory, i.e., has to be a constant
// (immediate or symbolic), try to emit it as such.
if (!Info.allowsRegister() && !Info.allowsMemory()) {
+ if (Info.requiresImmediateConstant()) {
+ llvm::APSInt AsmConst = InputExpr->EvaluateKnownConstInt(getContext());
+ return llvm::ConstantInt::get(getLLVMContext(), AsmConst);
+ }
+
Expr::EvalResult Result;
if (InputExpr->EvaluateAsInt(Result, getContext()))
return llvm::ConstantInt::get(getLLVMContext(), Result.Val.getInt());
- assert(!Info.requiresImmediateConstant() &&
- "Required-immediate inlineasm arg isn't constant?");
}
if (Info.allowsRegister() || !Info.allowsMemory())
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index d209266049e..b10b3d852c6 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -378,17 +378,17 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
<< InputExpr->getSourceRange());
} else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) {
if (!InputExpr->isValueDependent()) {
- Expr::EvalResult EVResult;
- if (!InputExpr->EvaluateAsInt(EVResult, Context))
+ llvm::SmallVector<PartialDiagnosticAt, 1> Diags;
+ llvm::APSInt Result = InputExpr->EvaluateKnownConstInt(Context, &Diags);
+ if (!Diags.empty())
return StmtError(
Diag(InputExpr->getBeginLoc(), diag::err_asm_immediate_expected)
<< Info.getConstraintStr() << InputExpr->getSourceRange());
- llvm::APSInt Result = EVResult.Val.getInt();
- if (!Info.isValidAsmImmediate(Result))
- return StmtError(Diag(InputExpr->getBeginLoc(),
- diag::err_invalid_asm_value_for_constraint)
- << Result.toString(10) << Info.getConstraintStr()
- << InputExpr->getSourceRange());
+ if (!Info.isValidAsmImmediate(Result))
+ return StmtError(Diag(InputExpr->getBeginLoc(),
+ diag::err_invalid_asm_value_for_constraint)
+ << Result.toString(10) << Info.getConstraintStr()
+ << InputExpr->getSourceRange());
}
} else {
diff --git a/clang/test/CodeGen/builtin-constant-p.c b/clang/test/CodeGen/builtin-constant-p.c
index 7f4e7d07cc6..f1cd06ad4aa 100644
--- a/clang/test/CodeGen/builtin-constant-p.c
+++ b/clang/test/CodeGen/builtin-constant-p.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O2 | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck --check-prefix=O0 %s
int a = 42;
@@ -166,3 +167,13 @@ struct { const char *t; int a; } test15[] = {
extern char test16_v;
struct { int a; } test16 = { __builtin_constant_p(test16_v) };
+
+extern unsigned long long test17_v;
+
+void test17() {
+ // O0: define void @test17
+ // O0: call void asm sideeffect "", {{.*}}(i32 -1)
+ // CHECK: define void @test17
+ // CHECK: call void asm sideeffect "", {{.*}}(i32 -1)
+ __asm__ __volatile__("" :: "n"( (__builtin_constant_p(test17_v) || 0) ? 1 : -1));
+}
OpenPOWER on IntegriCloud