aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-05-03 08:32:32 +0000
committerChris Lattner <sabre@nondot.org>2009-05-03 08:32:32 +0000
commit3351f1145aa91ddd8022fcd3ca16c219db9e8277 (patch)
tree30c654afec1843001d0a3ad1fa447d6269a31ead /lib/Sema/SemaStmt.cpp
parent58bce89d12b1dfba16637ce3754d6cb24c3099bb (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.cpp40
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;
}