Index: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -1056,6 +1056,7 @@ assert(OrigOperands.size() == FinalOperands.size() + 1 && "Opernand size mismatch"); + SmallVector, 2> Warnings; // Verify types match int RegClassID = -1; for (unsigned int i = 0; i < FinalOperands.size(); ++i) { @@ -1100,9 +1101,10 @@ if (FinalReg != OrigReg) { std::string RegName = IsSI ? "ES:(R|E)SI" : "ES:(R|E)DI"; - Warning(OrigOp.getStartLoc(), - "memory operand is only for determining the size, " + - RegName + " will be used for the location"); + Warnings.push_back(std::make_pair( + OrigOp.getStartLoc(), + "memory operand is only for determining the size, " + RegName + + " will be used for the location")); } FinalOp.Mem.Size = OrigOp.Mem.Size; @@ -1111,7 +1113,14 @@ } } - // Remove old operandss + // Produce warnings only if all the operands passed the adjustment - prevent + // legal cases like "movsd (%rax), %xmm0" mistakenly produce warnings + for (auto WarningMsg = Warnings.begin(); WarningMsg < Warnings.end(); + ++WarningMsg) { + Warning((*WarningMsg).first, (*WarningMsg).second); + } + + // Remove old operands for (unsigned int i = 0; i < FinalOperands.size(); ++i) OrigOperands.pop_back(); } Index: llvm/trunk/test/MC/X86/intel-syntax.s =================================================================== --- llvm/trunk/test/MC/X86/intel-syntax.s +++ llvm/trunk/test/MC/X86/intel-syntax.s @@ -1,4 +1,6 @@ -// RUN: llvm-mc -triple x86_64-unknown-unknown -x86-asm-syntax=intel %s | FileCheck %s +// RUN: llvm-mc -triple x86_64-unknown-unknown -x86-asm-syntax=intel %s > %t 2> %t.err +// RUN: FileCheck < %t %s +// RUN: FileCheck --check-prefix=CHECK-STDERR < %t.err %s _test: xor EAX, EAX @@ -755,26 +757,39 @@ ins byte ptr [eax], dx // CHECK: insb %dx, %es:(%edi) // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location +// CHECK-STDERR-NEXT: ins byte ptr [eax], dx outs dx, word ptr [eax] // CHECK: outsw (%esi), %dx // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location +// CHECK-STDERR-NEXT: outs dx, word ptr [eax] lods dword ptr [eax] // CHECK: lodsl (%esi), %eax // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location +// CHECK-STDERR-NEXT: lods dword ptr [eax] stos qword ptr [eax] // CHECK: stosq %rax, %es:(%edi) // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location +// CHECK-STDERR-NEXT: stos qword ptr [eax] scas byte ptr [eax] // CHECK: scasb %es:(%edi), %al // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location +// CHECK-STDERR-NEXT: scas byte ptr [eax] cmps word ptr [eax], word ptr [ebx] // CHECK: cmpsw %es:(%edi), (%esi) // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location +// CHECK-STDERR-NEXT: cmps word ptr [eax], word ptr [ebx] // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location +// CHECK-STDERR-NEXT: cmps word ptr [eax], word ptr [ebx] movs dword ptr [eax], dword ptr [ebx] // CHECK: movsl (%esi), %es:(%edi) // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)DI will be used for the location +// CHECK-STDERR-NEXT: movs dword ptr [eax], dword ptr [ebx] // CHECK-STDERR: memory operand is only for determining the size, ES:(R|E)SI will be used for the location +// CHECK-STDERR-NEXT: movs dword ptr [eax], dword ptr [ebx] + +movsd qword ptr [rax], xmm0 +// CHECK: movsd %xmm0, (%rax) +// CHECK-STDERR-NOT: movsd qword ptr [rax], xmm0 xlat byte ptr [eax] // CHECK: xlatb