diff options
author | Chris Lattner <sabre@nondot.org> | 2009-05-03 08:32:32 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-05-03 08:32:32 +0000 |
commit | 3351f1145aa91ddd8022fcd3ca16c219db9e8277 (patch) | |
tree | 30c654afec1843001d0a3ad1fa447d6269a31ead /lib/Sema/SemaStmt.cpp | |
parent | 58bce89d12b1dfba16637ce3754d6cb24c3099bb (diff) |
allow references to the larger value in a tied constraint
from the asm string, but reject references to the smaller one.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70679 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index cb237870f8..0c181ecf01 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1052,26 +1052,42 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, // They are ok if they are the same size. Tying void* to int is ok if // they are the same size, for example. This also allows tying void* to // int*. - if (Context.getTypeSize(OutTy) == Context.getTypeSize(InTy)) + uint64_t OutSize = Context.getTypeSize(OutTy); + uint64_t InSize = Context.getTypeSize(InTy); + if (OutSize == InSize) continue; - // If the input and output operands are not mentioned in the asm string, - // then we can promote them and the asm string won't notice. Check this + // If the smaller input/output operand is not mentioned in the asm string, + // then we can promote it and the asm string won't notice. Check this // case now. - bool MentionedInput = false; - bool MentionedOutput = false; + bool SmallerValueMentioned = false; for (unsigned p = 0, e = Pieces.size(); p != e; ++p) { AsmStmt::AsmStringPiece &Piece = Pieces[p]; if (!Piece.isOperand()) continue; - MentionedInput |= Piece.getOperandNo() == i+NumOutputs; - MentionedOutput |= Piece.getOperandNo() == TiedTo; + + // If this is a reference to the input and if the input was the smaller + // one, then we have to reject this asm. + if (Piece.getOperandNo() == i+NumOutputs) { + if (InSize < OutSize) { + SmallerValueMentioned = true; + break; + } + } + + // If this is a reference to the input and if the input was the smaller + // one, then we have to reject this asm. + if (Piece.getOperandNo() == TiedTo) { + if (InSize > OutSize) { + SmallerValueMentioned = true; + break; + } + } } - // If neither the input nor the output was mentioned in the asm string, - // and if the output was a register, just extend the shorter one to the - // size of the larger one. - // TODO: if only the larger one is mentioned, we could also support this. - if (!MentionedInput && !MentionedOutput && + // If the smaller value wasn't mentioned in the asm string, and if the + // output was a register, just extend the shorter one to the size of the + // larger one. + if (!SmallerValueMentioned && OutputConstraintInfos[TiedTo].allowsRegister()) continue; } |