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

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 13 13:51:27 PDT 2018


Author: ctopper
Date: Thu Sep 13 13:51:27 2018
New Revision: 342176

URL: http://llvm.org/viewvc/llvm-project?rev=342176&view=rev
Log:
[MachineInstr] In addRegisterKilled and addRegisterDead, don't remove operands from inline assembly instructions if they have an associated flag operand.

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 fixes this by preventing the removal when a flag operand is present.

The included test case was generated by MS inline assembly. Longer term maybe we should fix the inline assembly parsing to not generate redundant operands.

Differential Revision: https://reviews.llvm.org/D51829

Added:
    llvm/trunk/test/CodeGen/X86/ms-inline-asm-redundant-clobber.ll
Modified:
    llvm/trunk/lib/CodeGen/MachineInstr.cpp

Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=342176&r1=342175&r2=342176&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original)
+++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Thu Sep 13 13:51:27 2018
@@ -1766,7 +1766,8 @@ bool MachineInstr::addRegisterKilled(uns
   // 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);
@@ -1830,7 +1831,8 @@ bool MachineInstr::addRegisterDead(unsig
   // 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);

Added: llvm/trunk/test/CodeGen/X86/ms-inline-asm-redundant-clobber.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/ms-inline-asm-redundant-clobber.ll?rev=342176&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/ms-inline-asm-redundant-clobber.ll (added)
+++ llvm/trunk/test/CodeGen/X86/ms-inline-asm-redundant-clobber.ll Thu Sep 13 13:51:27 2018
@@ -0,0 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+; This used to crash due to Live Variable analysis removing the redundant eax
+; and edx clobbers, but not removing the inline asm flag operands that proceed
+; them.
+
+ at test_mem = dso_local global [16 x i8] c"UUUUUUUUUUUUUUUU", align 16
+
+; Function Attrs: nounwind uwtable
+define dso_local void @foo() local_unnamed_addr {
+; CHECK-LABEL: foo:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    #APP
+; CHECK:         clc
+; CHECK-NEXT:    cmpxchg8b {{.*}}(%rip)
+; CHECK-NEXT:    cmpxchg16b {{.*}}(%rip)
+; CHECK-NEXT:    clc
+; CHECK:         #NO_APP
+; CHECK-NEXT:    retq
+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
+}




More information about the llvm-commits mailing list