Skip to content

Commit

Permalink
Emit ASM input in a constant context
Browse files Browse the repository at this point in the history
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
  • Loading branch information
isanbard committed Dec 18, 2018
1 parent bb3d3a8 commit aa77513
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 10 deletions.
2 changes: 2 additions & 0 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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':
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
16 changes: 8 additions & 8 deletions clang/lib/Sema/SemaStmtAsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
11 changes: 11 additions & 0 deletions clang/test/CodeGen/builtin-constant-p.c
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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));
}

0 comments on commit aa77513

Please sign in to comment.