diff options
| author | Eli Friedman <efriedma@quicinc.com> | 2019-03-14 19:46:51 +0000 |
|---|---|---|
| committer | Eli Friedman <efriedma@quicinc.com> | 2019-03-14 19:46:51 +0000 |
| commit | 4af1c265025e003d25ac419b38d736d9bbf68b3c (patch) | |
| tree | 81fecad099139b3aa60e4f9b6fba2883dfed5421 /clang | |
| parent | 38f07b1966a9ca8c2969c40dca30ed05ccb78b67 (diff) | |
| download | bcm5719-llvm-4af1c265025e003d25ac419b38d736d9bbf68b3c.tar.gz bcm5719-llvm-4af1c265025e003d25ac419b38d736d9bbf68b3c.zip | |
[CodeGen] Consider tied operands when adjusting inline asm operands.
The constraint "0" in the following asm did not consider the its
relationship with "=y" when try to replace the type of the operands.
asm ("nop" : "=y"(Mu8_1 ) : "0"(Mu8_0 ));
Patch by Xiang Zhang.
Differential Revision: https://reviews.llvm.org/D56990
llvm-svn: 356196
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 10 | ||||
| -rw-r--r-- | clang/test/CodeGen/asm-inout.c | 9 |
2 files changed, 17 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index b9905a2b3cc..c617b198d76 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -1939,6 +1939,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { std::vector<llvm::Value*> InOutArgs; std::vector<llvm::Type*> InOutArgTypes; + // Keep track of out constraints for tied input operand. + std::vector<std::string> OutputConstraints; + // An inline asm can be marked readonly if it meets the following conditions: // - it doesn't have any sideeffects // - it doesn't clobber memory @@ -1961,7 +1964,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr, getTarget(), CGM, S, Info.earlyClobber()); - + OutputConstraints.push_back(OutputConstraint); LValue Dest = EmitLValue(OutExpr); if (!Constraints.empty()) Constraints += ','; @@ -2079,6 +2082,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { InputConstraint, *InputExpr->IgnoreParenNoopCasts(getContext()), getTarget(), CGM, S, false /* No EarlyClobber */); + std::string ReplaceConstraint (InputConstraint); llvm::Value *Arg = EmitAsmInput(Info, InputExpr, Constraints); // If this input argument is tied to a larger output result, extend the @@ -2106,9 +2110,11 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Arg = Builder.CreateFPExt(Arg, OutputTy); } } + // Deal with the tied operands' constraint code in adjustInlineAsmType. + ReplaceConstraint = OutputConstraints[Output]; } if (llvm::Type* AdjTy = - getTargetHooks().adjustInlineAsmType(*this, InputConstraint, + getTargetHooks().adjustInlineAsmType(*this, ReplaceConstraint, Arg->getType())) Arg = Builder.CreateBitCast(Arg, AdjTy); else diff --git a/clang/test/CodeGen/asm-inout.c b/clang/test/CodeGen/asm-inout.c index e5da5c5e934..411f6fadac1 100644 --- a/clang/test/CodeGen/asm-inout.c +++ b/clang/test/CodeGen/asm-inout.c @@ -46,3 +46,12 @@ __m64 test5(__m64 __A, __m64 __B) { asm ("pmulhuw %1, %0\n\t" : "+y" (__A) : "y" (__B)); return __A; } + +// CHECK: @test6 +int test6(void) { + typedef unsigned char __attribute__((vector_size(8))) _m64u8; + _m64u8 __attribute__((aligned(16))) Mu8_0, __attribute__((aligned(16))) Mu8_1; + // CHECK: call x86_mmx asm "nop", "=y,0,~{dirflag},~{fpsr},~{flags}"(x86_mmx %1) + asm ("nop" : "=y"(Mu8_1 ) : "0"(Mu8_0 )); + return 0; +} |

