[llvm] 7669455 - [X86][FastISel] Fix with.overflow eflags clobber (PR49587)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 29 14:08:59 PDT 2021


Author: Nikita Popov
Date: 2021-03-29T23:08:47+02:00
New Revision: 7669455df49e6fc8ae7d9f4bd4ee95bb20e7eb6e

URL: https://github.com/llvm/llvm-project/commit/7669455df49e6fc8ae7d9f4bd4ee95bb20e7eb6e
DIFF: https://github.com/llvm/llvm-project/commit/7669455df49e6fc8ae7d9f4bd4ee95bb20e7eb6e.diff

LOG: [X86][FastISel] Fix with.overflow eflags clobber (PR49587)

If the successor block has a phi node, then additional moves may
be inserted into predecessors, which may clobber eflags. Don't try
to fold the with.overflow result into the branch in that case.

This is done by explicitly checking for any phis in successor
blocks, not sure if there's some more principled way to address
this. Other fused compare and branch patterns avoid the issue by
emitting the comparison when handling the branch, so that no
instructions may be inserted in between. In this case, the
with.overflow call is emitted separately (and I don't think this
is avoidable, as it will generally have at least two users).

Fixes https://bugs.llvm.org/show_bug.cgi?id=49587.

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

Added: 
    

Modified: 
    llvm/lib/Target/X86/X86FastISel.cpp
    llvm/test/CodeGen/X86/pr49587.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp
index b37cd25c7de1..a04c9d6c0454 100644
--- a/llvm/lib/Target/X86/X86FastISel.cpp
+++ b/llvm/lib/Target/X86/X86FastISel.cpp
@@ -284,6 +284,14 @@ bool X86FastISel::foldX86XALUIntrinsic(X86::CondCode &CC, const Instruction *I,
       return false;
   }
 
+  // Make sure no potentially eflags clobbering phi moves can be inserted in
+  // between.
+  auto HasPhis = [](const BasicBlock *Succ) {
+    return !llvm::empty(Succ->phis());
+  };
+  if (I->isTerminator() && llvm::any_of(successors(I), HasPhis))
+    return false;
+
   CC = TmpCC;
   return true;
 }

diff  --git a/llvm/test/CodeGen/X86/pr49587.ll b/llvm/test/CodeGen/X86/pr49587.ll
index 343f1a0149c0..7dc54a526608 100644
--- a/llvm/test/CodeGen/X86/pr49587.ll
+++ b/llvm/test/CodeGen/X86/pr49587.ll
@@ -5,10 +5,11 @@ define i32 @test(i64 %arg) nounwind {
 ; CHECK-LABEL: test:
 ; CHECK:       # %bb.0: # %entry
 ; CHECK-NEXT:    subq $1, %rdi
-; CHECK-NEXT:    setb %al
+; CHECK-NEXT:    setb %cl
 ; CHECK-NEXT:    xorl %eax, %eax
+; CHECK-NEXT:    testb $1, %cl
 ; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill
-; CHECK-NEXT:    jb .LBB0_2
+; CHECK-NEXT:    jne .LBB0_2
 ; CHECK-NEXT:  # %bb.1: # %no_overflow
 ; CHECK-NEXT:    movl $1, %eax
 ; CHECK-NEXT:    movl %eax, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill


        


More information about the llvm-commits mailing list