summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/TargetInfo.cpp2
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp7
-rw-r--r--clang/lib/Sema/SemaStmtAsm.cpp16
3 files changed, 15 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 {
OpenPOWER on IntegriCloud