summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorEli Friedman <efriedma@quicinc.com>2019-03-14 19:46:51 +0000
committerEli Friedman <efriedma@quicinc.com>2019-03-14 19:46:51 +0000
commit4af1c265025e003d25ac419b38d736d9bbf68b3c (patch)
tree81fecad099139b3aa60e4f9b6fba2883dfed5421 /clang
parent38f07b1966a9ca8c2969c40dca30ed05ccb78b67 (diff)
downloadbcm5719-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.cpp10
-rw-r--r--clang/test/CodeGen/asm-inout.c9
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;
+}
OpenPOWER on IntegriCloud