[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
This commit is contained in:
Eli Friedman 2019-03-14 19:46:51 +00:00
parent 38f07b1966
commit 4af1c26502
2 changed files with 17 additions and 2 deletions

View File

@ -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

View File

@ -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;
}