pengfei updated this revision to Diff 413453. pengfei added a comment. Herald added a project: All.
Refactor. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D107141/new/ https://reviews.llvm.org/D107141 Files: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/CodeGen/CGStmt.cpp clang/lib/Sema/SemaStmtAsm.cpp clang/test/Sema/asm.c
Index: clang/test/Sema/asm.c =================================================================== --- clang/test/Sema/asm.c +++ clang/test/Sema/asm.c @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -Wno-private-extern -triple i386-pc-linux-gnu -verify -fsyntax-only +// RUN: %clang_cc1 %s -Wno-private-extern -triple x86_64-pc-linux-gnu -verify -fsyntax-only -DTEST_X86_64 void f(void) { @@ -313,3 +314,69 @@ asm ("jne %l0":::); asm goto ("jne %l0"::::lab); } + +typedef struct test19_a { + int a; + char b; +} test19_a; + +typedef struct test19_b { + int a; + int b; + int c; +} test19_b; + +typedef struct test19_c { + char a; + char b; +} test19_c; + +typedef struct test19_d { + char a; + char b; + char c; + char d; +} test19_d; + +typedef struct test19_e { + int a; + int b; + int c; + int d; +} test19_e; + +#ifdef TEST_X86_64 +void test19(long long x) +{ + test19_a a; + test19_b b; + test19_c c; + test19_d d; + test19_e e; + asm ("" : "=rm" (a): "0" (1)); // no-error + asm ("" : "=rm" (d): "0" (1)); // no-error + asm ("" : "=rm" (c): "0" (x)); // no-error + asm ("" : "=rm" (x): "0" (a)); // no-error + asm ("" : "=rm" (a): "0" (d)); // no-error + asm ("" : "=rm" (b): "0" (1)); // expected-error {{impossible constraint in asm: can't store value into a register}} + asm ("" : "=rm" (e): "0" (1)); // expected-error {{impossible constraint in asm: can't store value into a register}} + asm ("" : "=rm" (x): "0" (e)); // no-error +} +#else +void test19(long long x) +{ + test19_a a; + test19_b b; + test19_c c; + test19_d d; + test19_e e; + asm ("" : "=rm" (a): "0" (1)); // expected-error {{impossible constraint in asm: can't store value into a register}} + asm ("" : "=rm" (d): "0" (1)); // no-error + asm ("" : "=rm" (c): "0" (x)); // no-error + asm ("" : "=rm" (x): "0" (a)); // no-error + asm ("" : "=rm" (a): "0" (d)); // expected-error {{impossible constraint in asm: can't store value into a register}} + asm ("" : "=rm" (b): "0" (1)); // expected-error {{impossible constraint in asm: can't store value into a register}} + asm ("" : "=rm" (e): "0" (1)); // expected-error {{impossible constraint in asm: can't store value into a register}} + asm ("" : "=rm" (x): "0" (e)); // expected-error {{impossible constraint in asm: can't store value into a register}} +} +#endif Index: clang/lib/Sema/SemaStmtAsm.cpp =================================================================== --- clang/lib/Sema/SemaStmtAsm.cpp +++ clang/lib/Sema/SemaStmtAsm.cpp @@ -618,14 +618,16 @@ AD_Int, AD_FP, AD_Other } InputDomain, OutputDomain; - if (InTy->isIntegerType() || InTy->isPointerType()) + if (InTy->isIntegerType() || InTy->isPointerType() || + InTy->isStructureType() || InTy->isConstantArrayType()) InputDomain = AD_Int; else if (InTy->isRealFloatingType()) InputDomain = AD_FP; else InputDomain = AD_Other; - if (OutTy->isIntegerType() || OutTy->isPointerType()) + if (OutTy->isIntegerType() || OutTy->isPointerType() || + OutTy->isStructureType() || OutTy->isConstantArrayType()) OutputDomain = AD_Int; else if (OutTy->isRealFloatingType()) OutputDomain = AD_FP; @@ -667,8 +669,17 @@ // output was a register, just extend the shorter one to the size of the // larger one. if (!SmallerValueMentioned && InputDomain != AD_Other && - OutputConstraintInfos[TiedTo].allowsRegister()) + OutputConstraintInfos[TiedTo].allowsRegister()) { + // FIXME: GCC supports the OutSize to be 128 at maximum. Currently codegen + // crash when the size larger than the register size. So we limit it here. + if (OutputDomain != AD_Int) + continue; + if (OutSize < 8 || OutSize > Context.getTypeSize(Context.getSizeType()) || + !llvm::isPowerOf2_32(OutSize)) + targetDiag(OutputExpr->getExprLoc(), diag::err_store_value_to_reg); + continue; + } // Either both of the operands were mentioned or the smaller one was // mentioned. One more special case that we'll allow: if the tied input is Index: clang/lib/CodeGen/CGStmt.cpp =================================================================== --- clang/lib/CodeGen/CGStmt.cpp +++ clang/lib/CodeGen/CGStmt.cpp @@ -2725,9 +2725,8 @@ QualType Ty = getContext().getIntTypeForBitwidth(Size, /*Signed*/ false); if (Ty.isNull()) { const Expr *OutExpr = S.getOutputExpr(i); - CGM.Error( - OutExpr->getExprLoc(), - "impossible constraint in asm: can't store value into a register"); + CGM.getDiags().Report(OutExpr->getExprLoc(), + diag::err_store_value_to_reg); return; } Dest = MakeAddrLValue(A, Ty); Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8763,6 +8763,8 @@ " in asm %select{input|output}1 with a memory constraint '%2'">; def err_asm_input_duplicate_match : Error< "more than one input constraint matches the same output '%0'">; + def err_store_value_to_reg : Error< + "impossible constraint in asm: can't store value into a register">; def warn_asm_label_on_auto_decl : Warning< "ignored asm label '%0' on automatic variable">;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits