[PATCH] D51829: [MachineInstr] In addRegisterKilled and addRegisterDead, don't remove operands from inline assembly instructions if they have an associated flag operand.

Craig Topper via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 7 17:47:43 PDT 2018


craig.topper created this revision.
craig.topper added reviewers: MatzeB, efriedma, rnk.
Herald added a subscriber: jfb.

INLINEASM instructions use extra operands to carry flags. If a register operand is removed without removing the flag operand, then the flags will no longer make sense.

This patch tries to fix this by preventing the removal when a flag operand is present. I have no idea if this is the right thing to do here.

This fixes a crash for the following test. Previously the Live Variable analysis would remove the edx and eax clobber operands since they are redundant with the rax and rdx operands. But it did not remove their flag operands. A later pass expected a register operand to follow the flag operand, but it was no longer there.

This code was created with MS inline assembly which added clobbers for each instruction without knowing about sub/super registers.

target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@test_mem = dso_local global [16 x i8] c"UUUUUUUUUUUUUUUU", align 16

; Function Attrs: nounwind uwtable
define dso_local void @foo() local_unnamed_addr {
entry:

  tail call void asm sideeffect inteldialect "clc\0A\09cmpxchg8b $0\0A\09cmpxchg16b $1\0A\09clc", "=*m,=*m,~{eax},~{edx},~{flags},~{rax},~{rdx},~{dirflag},~{fpsr},~{flags}"([16 x i8]* nonnull @test_mem, [16 x i8]* nonnull @test_mem) #1
  ret void

}


Repository:
  rL LLVM

https://reviews.llvm.org/D51829

Files:
  lib/CodeGen/MachineInstr.cpp


Index: lib/CodeGen/MachineInstr.cpp
===================================================================
--- lib/CodeGen/MachineInstr.cpp
+++ lib/CodeGen/MachineInstr.cpp
@@ -1760,7 +1760,8 @@
   // Trim unneeded kill operands.
   while (!DeadOps.empty()) {
     unsigned OpIdx = DeadOps.back();
-    if (getOperand(OpIdx).isImplicit())
+    if (getOperand(OpIdx).isImplicit() &&
+        (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
       RemoveOperand(OpIdx);
     else
       getOperand(OpIdx).setIsKill(false);
@@ -1824,7 +1825,8 @@
   // Trim unneeded dead operands.
   while (!DeadOps.empty()) {
     unsigned OpIdx = DeadOps.back();
-    if (getOperand(OpIdx).isImplicit())
+    if (getOperand(OpIdx).isImplicit() &&
+        (!isInlineAsm() || findInlineAsmFlagIdx(OpIdx) < 0))
       RemoveOperand(OpIdx);
     else
       getOperand(OpIdx).setIsDead(false);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D51829.164557.patch
Type: text/x-patch
Size: 876 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180908/0cc0a49b/attachment.bin>


More information about the llvm-commits mailing list