Merged to release_80 in r355674.
On Wed, Mar 6, 2019 at 11:25 AM Hans Wennborg via cfe-commits <cfe-commits@lists.llvm.org> wrote: > > Author: hans > Date: Wed Mar 6 02:26:19 2019 > New Revision: 355491 > > URL: http://llvm.org/viewvc/llvm-project?rev=355491&view=rev > Log: > Inline asm constraints: allow ICE-like pointers for the "n" constraint > (PR40890) > > Apparently GCC allows this, and there's code relying on it (see bug). > > The idea is to allow expression that would have been allowed if they > were cast to int. So I based the code on how such a cast would be done > (the CK_PointerToIntegral case in IntExprEvaluator::VisitCastExpr()). > > Differential Revision: https://reviews.llvm.org/D58821 > > Modified: > cfe/trunk/include/clang/AST/APValue.h > cfe/trunk/lib/AST/APValue.cpp > cfe/trunk/lib/AST/ExprConstant.cpp > cfe/trunk/lib/CodeGen/CGStmt.cpp > cfe/trunk/lib/Sema/SemaStmtAsm.cpp > cfe/trunk/test/CodeGen/x86-64-inline-asm.c > cfe/trunk/test/Sema/inline-asm-validate-x86.c > > Modified: cfe/trunk/include/clang/AST/APValue.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/APValue.h?rev=355491&r1=355490&r2=355491&view=diff > ============================================================================== > --- cfe/trunk/include/clang/AST/APValue.h (original) > +++ cfe/trunk/include/clang/AST/APValue.h Wed Mar 6 02:26:19 2019 > @@ -262,6 +262,12 @@ public: > return const_cast<APValue*>(this)->getInt(); > } > > + /// Try to convert this value to an integral constant. This works if it's > an > + /// integer, null pointer, or offset from a null pointer. Returns true on > + /// success. > + bool toIntegralConstant(APSInt &Result, QualType SrcTy, > + const ASTContext &Ctx) const; > + > APFloat &getFloat() { > assert(isFloat() && "Invalid accessor"); > return *(APFloat*)(char*)Data.buffer; > > Modified: cfe/trunk/lib/AST/APValue.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/APValue.cpp?rev=355491&r1=355490&r2=355491&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/APValue.cpp (original) > +++ cfe/trunk/lib/AST/APValue.cpp Wed Mar 6 02:26:19 2019 > @@ -614,6 +614,26 @@ std::string APValue::getAsString(ASTCont > return Result; > } > > +bool APValue::toIntegralConstant(APSInt &Result, QualType SrcTy, > + const ASTContext &Ctx) const { > + if (isInt()) { > + Result = getInt(); > + return true; > + } > + > + if (isLValue() && isNullPointer()) { > + Result = Ctx.MakeIntValue(Ctx.getTargetNullPointerValue(SrcTy), SrcTy); > + return true; > + } > + > + if (isLValue() && !getLValueBase()) { > + Result = Ctx.MakeIntValue(getLValueOffset().getQuantity(), SrcTy); > + return true; > + } > + > + return false; > +} > + > const APValue::LValueBase APValue::getLValueBase() const { > assert(isLValue() && "Invalid accessor"); > return ((const LV*)(const void*)Data.buffer)->Base; > > Modified: cfe/trunk/lib/AST/ExprConstant.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=355491&r1=355490&r2=355491&view=diff > ============================================================================== > --- cfe/trunk/lib/AST/ExprConstant.cpp (original) > +++ cfe/trunk/lib/AST/ExprConstant.cpp Wed Mar 6 02:26:19 2019 > @@ -9872,13 +9872,12 @@ bool IntExprEvaluator::VisitCastExpr(con > return true; > } > > - uint64_t V; > - if (LV.isNullPointer()) > - V = Info.Ctx.getTargetNullPointerValue(SrcType); > - else > - V = LV.getLValueOffset().getQuantity(); > + APSInt AsInt; > + APValue V; > + LV.moveInto(V); > + if (!V.toIntegralConstant(AsInt, SrcType, Info.Ctx)) > + llvm_unreachable("Can't cast this!"); > > - APSInt AsInt = Info.Ctx.MakeIntValue(V, SrcType); > return Success(HandleIntToIntCast(Info, E, DestType, SrcType, AsInt), E); > } > > > Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=355491&r1=355490&r2=355491&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CGStmt.cpp (original) > +++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Mar 6 02:26:19 2019 > @@ -1838,8 +1838,15 @@ llvm::Value* CodeGenFunction::EmitAsmInp > // (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 EVResult; > + InputExpr->EvaluateAsRValue(EVResult, getContext(), true); > + > + llvm::APSInt IntResult; > + if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), > + getContext())) > + llvm_unreachable("Invalid immediate constant!"); > + > + return llvm::ConstantInt::get(getLLVMContext(), IntResult); > } > > Expr::EvalResult Result; > > Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=355491&r1=355490&r2=355491&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original) > +++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Wed Mar 6 02:26:19 2019 > @@ -385,11 +385,20 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceL > return StmtError( > Diag(InputExpr->getBeginLoc(), > diag::err_asm_immediate_expected) > << Info.getConstraintStr() << InputExpr->getSourceRange()); > - llvm::APSInt Result = EVResult.Val.getInt(); > - if (!Info.isValidAsmImmediate(Result)) > + > + // For compatibility with GCC, we also allow pointers that would be > + // integral constant expressions if they were cast to int. > + llvm::APSInt IntResult; > + if (!EVResult.Val.toIntegralConstant(IntResult, InputExpr->getType(), > + Context)) > + return StmtError( > + Diag(InputExpr->getBeginLoc(), > diag::err_asm_immediate_expected) > + << Info.getConstraintStr() << InputExpr->getSourceRange()); > + > + if (!Info.isValidAsmImmediate(IntResult)) > return StmtError(Diag(InputExpr->getBeginLoc(), > diag::err_invalid_asm_value_for_constraint) > - << Result.toString(10) << Info.getConstraintStr() > + << IntResult.toString(10) << > Info.getConstraintStr() > << InputExpr->getSourceRange()); > } > > > Modified: cfe/trunk/test/CodeGen/x86-64-inline-asm.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/x86-64-inline-asm.c?rev=355491&r1=355490&r2=355491&view=diff > ============================================================================== > --- cfe/trunk/test/CodeGen/x86-64-inline-asm.c (original) > +++ cfe/trunk/test/CodeGen/x86-64-inline-asm.c Wed Mar 6 02:26:19 2019 > @@ -1,6 +1,7 @@ > // REQUIRES: x86-registered-target > // RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -DWARN -verify > // RUN: %clang_cc1 -triple x86_64 %s -S -o /dev/null -Werror -verify > +// RUN: %clang_cc1 -triple x86_64-linux-gnu %s -S -o - | FileCheck %s > void f() { > asm("movaps %xmm3, (%esi, 2)"); > // expected-note@1 {{instantiated into assembly here}} > @@ -15,3 +16,17 @@ static unsigned var[1] = {}; > void g(void) { asm volatile("movd %%xmm0, %0" > : > : "m"(var)); } > + > +void pr40890(void) { > + struct s { > + int a, b; > + } s; > + __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a)); > + __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b)); > + __asm__ __volatile__("\n#define BEEF abcd%0\n" : : > "n"((int*)0xdeadbeeeeeef)); > + > +// CHECK-LABEL: pr40890 > +// CHECK: #define S_A abcd$0 > +// CHECK: #define S_B abcd$4 > +// CHECK: #define BEEF abcd$244837814038255 > +} > > Modified: cfe/trunk/test/Sema/inline-asm-validate-x86.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/inline-asm-validate-x86.c?rev=355491&r1=355490&r2=355491&view=diff > ============================================================================== > --- cfe/trunk/test/Sema/inline-asm-validate-x86.c (original) > +++ cfe/trunk/test/Sema/inline-asm-validate-x86.c Wed Mar 6 02:26:19 2019 > @@ -1,5 +1,5 @@ > // RUN: %clang_cc1 -triple i686 -fsyntax-only -verify %s > -// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify %s > +// RUN: %clang_cc1 -triple x86_64 -fsyntax-only -verify -DAMD64 %s > > void I(int i, int j) { > static const int BelowMin = -1; > @@ -137,3 +137,21 @@ void O(int i, int j) { > : "0"(i), "O"(64)); // expected-no-error > } > > +void pr40890(void) { > + struct s { > + int a, b; > + }; > + static struct s s; > + // This null pointer can be used as an integer constant expression. > + __asm__ __volatile__("\n#define S_A abcd%0\n" : : "n"(&((struct s*)0)->a)); > + // This offset-from-null pointer can be used as an integer constant > expression. > + __asm__ __volatile__("\n#define S_B abcd%0\n" : : "n"(&((struct s*)0)->b)); > + // This pointer cannot be used as an integer constant expression. > + __asm__ __volatile__("\n#define GLOBAL_A abcd%0\n" : : "n"(&s.a)); // > expected-error{{constraint 'n' expects an integer constant expression}} > + // Floating-point is also not okay. > + __asm__ __volatile__("\n#define PI abcd%0\n" : : "n"(3.14f)); // > expected-error{{constraint 'n' expects an integer constant expression}} > +#ifdef AMD64 > + // This arbitrary pointer is fine. > + __asm__ __volatile__("\n#define BEEF abcd%0\n" : : > "n"((int*)0xdeadbeeeeeef)); > +#endif > +} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits