r239549 - [CodeGen] Emit Constants for immediate inlineasm arguments.
Ahmed Bougacha
ahmed.bougacha at gmail.com
Fri Jun 12 18:24:49 PDT 2015
On Fri, Jun 12, 2015 at 12:46 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> On Fri, Jun 12, 2015 at 11:31 AM, Ahmed Bougacha <ahmed.bougacha at gmail.com>
> wrote:
>>
>> On Thu, Jun 11, 2015 at 2:17 PM, Richard Smith <richard at metafoo.co.uk>
>> wrote:
>> > On Thu, Jun 11, 2015 at 2:13 PM, Richard Smith <richard at metafoo.co.uk>
>> > wrote:
>> >>
>> >> On Thu, Jun 11, 2015 at 11:19 AM, Ahmed Bougacha
>> >> <ahmed.bougacha at gmail.com> wrote:
>> >>>
>> >>> Author: ab
>> >>> Date: Thu Jun 11 13:19:34 2015
>> >>> New Revision: 239549
>> >>>
>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=239549&view=rev
>> >>> Log:
>> >>> [CodeGen] Emit Constants for immediate inlineasm arguments.
>> >>>
>> >>> For inline assembly immediate constraints, we currently always use
>> >>> EmitScalarExpr, instead of directly emitting the constant. When the
>> >>> overflow sanitizer is enabled, this generates overflow intrinsics
>> >>> instead of constants.
>> >>>
>> >>> Instead, emit a constant for constraints that either require an
>> >>> immediate (e.g. 'I' on X86), or only accepts constants (immediate
>> >>> or symbolic; i.e., don't accept registers or memory).
>> >>>
>> >>> Fixes PR19763.
>> >>>
>> >>> Differential Revision: http://reviews.llvm.org/D10255
>> >>>
>> >>> Added:
>> >>> cfe/trunk/test/CodeGen/inline-asm-immediate-ubsan.c
>> >>> Modified:
>> >>> cfe/trunk/lib/CodeGen/CGStmt.cpp
>> >>>
>> >>> Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
>> >>> URL:
>> >>>
>> >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=239549&r1=239548&r2=239549&view=diff
>> >>>
>> >>>
>> >>> ==============================================================================
>> >>> --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
>> >>> +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu Jun 11 13:19:34 2015
>> >>> @@ -1750,6 +1750,16 @@ llvm::Value* CodeGenFunction::EmitAsmInp
>> >>> const
>> >>> TargetInfo::ConstraintInfo &Info,
>> >>> const Expr *InputExpr,
>> >>> std::string
>> >>> &ConstraintStr) {
>> >>> + // 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()) {
>> >>> + llvm::APSInt Result;
>> >>> + if (InputExpr->isIntegerConstantExpr(Result, getContext()))
>> >>
>> >>
>> >> Please use EvaluateKnownConstInt here instead. This construct will
>> >> redundantly re-check whether the expression is an ICE first.
>> >
>> >
>> > Ah, sorry, you don't know that this is constant except in the
>> > requiresImmediateConstant() case. You should be calling EvaluateAsInt
>> > here
>> > instead.
Done in r239651.
>> Yes, I'm relying on the ICE-checking here, but I just realized Sema
>> also calls EvaluateAsInt, and because of that doesn't check that the
>> requiresImmediateConstant() operand is an ICE.
>>
>> Does the below patch make sense? It lets us emit an error for the
>> overflowing "constant" expressions we want to catch here.
>
>
> Yes, that looks fine. Please also include a testcase (if you need an example
> of a non-ICE that we can evaluate, something like "(long)(void*)0" should
> work).
Perhaps isICE() isn't appropriate, as it's not true for C static const
(used in e.g. test/Sema/inline-asm-validate-x86.c).
Really, all I want here is not to silently ignore overflow; here's
another hacky try:
diff --git a/cfe/trunk/lib/Sema/SemaStmtAsm.cpp
b/cfe/trunk/lib/Sema/SemaStmtAsm.cpp
--- a/cfe/trunk/lib/Sema/SemaStmtAsm.cpp
+++ b/cfe/trunk/lib/Sema/SemaStmtAsm.cpp
@@ -255,6 +255,7 @@
<< InputExpr->getSourceRange());
} else if (Info.requiresImmediateConstant() && !Info.allowsRegister()) {
llvm::APSInt Result;
+ CheckForIntOverflow(InputExpr);
if (!InputExpr->EvaluateAsInt(Result, Context))
return StmtError(
Diag(InputExpr->getLocStart(), diag::err_asm_immediate_expected)
I thought this would be checked for any expr in any context, but it's
only currently done for full-exprs (so IIUC doesn't apply for
inline-asm operands). Is there a reason for that? I can see it being
expensive, but it could be useful. For instance, currently we'll warn
on:
int a = (4 * (1 << 30));
but not on:
foo(int a);
foo((4 * (1 << 30)));
-Ahmed
>> With that, we can use EvaluateAsInt in CGStmt.cpp, and we'll do the
>> right thing for all combinations except overflowing "i". I'm not
>> quite sure how to handle that, if it's even possible in the general
>> case: what happens if a link-time constant expression overflows?
>
>
> In C++11 onwards, it's not an ICE. In any case, the evaluator will produce
> the two's complement result.
>
>> Thanks for having a look!
>> -Ahmed
>>
>>
>> diff --git a/cfe/trunk/lib/Sema/SemaStmtAsm.cpp
>> b/cfe/trunk/lib/Sema/SemaStmtAsm.cpp
>> --- a/cfe/trunk/lib/Sema/SemaStmtAsm.cpp (revision 239545)
>> +++ b/cfe/trunk/lib/Sema/SemaStmtAsm.cpp (working copy)
>> @@ -255,7 +255,7 @@
>> << InputExpr->getSourceRange());
>> } else if (Info.requiresImmediateConstant() &&
>> !Info.allowsRegister()) {
>> llvm::APSInt Result;
>> - if (!InputExpr->EvaluateAsInt(Result, Context))
>> + if (!InputExpr->isIntegerConstantExpr(Result, Context))
>> return StmtError(
>> Diag(InputExpr->getLocStart(),
>> diag::err_asm_immediate_expected)
>> << Info.getConstraintStr() << InputExpr->getSourceRange());
>
>
More information about the cfe-commits
mailing list