Set EFLAGS correctly in EmitLoweredSelect on X86.
authorLang Hames <lhames@gmail.com>
Thu, 2 Feb 2012 07:48:37 +0000 (07:48 +0000)
committerLang Hames <lhames@gmail.com>
Thu, 2 Feb 2012 07:48:37 +0000 (07:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149597 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelLowering.cpp
test/CodeGen/X86/uint64-to-float.ll

index 658837c83b012d6130fb6f7bf639506eeb5c1d64..2e8909a5c397c23a02be5b4be303a2f84f55843c 100644 (file)
@@ -12059,6 +12059,31 @@ X86TargetLowering::EmitVAStartSaveXMMRegsWithCustomInserter(
   return EndMBB;
 }
 
+// Check whether the given instruction should have had a kill marker on
+// the EFLAGS operand.
+static bool shouldHaveEFlagsKill(MachineBasicBlock::iterator SelectItr,
+                                 MachineBasicBlock* BB) {
+  for (MachineBasicBlock::iterator miI(next(SelectItr)), miE = BB->end();
+       miI != miE; ++miI) {
+    const MachineInstr& mi = *miI;
+    if (mi.readsRegister(X86::EFLAGS)) {
+      return false;
+    }
+    if (mi.definesRegister(X86::EFLAGS)) {
+      // Should have kill-flag - update below.
+      break;
+    }
+  }
+
+  // We found a def, or hit the end of the basic block. SelectMI should have a
+  // kill flag on EFLAGS.
+  MachineInstr& SelectMI = *SelectItr;
+  MachineOperand* EFlagsOp = SelectMI.findRegisterUseOperand(X86::EFLAGS);
+  assert(EFlagsOp != 0 && "No EFLAGS operand on select instruction?");
+  EFlagsOp->setIsKill();
+  return true;
+}
+
 MachineBasicBlock *
 X86TargetLowering::EmitLoweredSelect(MachineInstr *MI,
                                      MachineBasicBlock *BB) const {
@@ -12089,8 +12114,10 @@ X86TargetLowering::EmitLoweredSelect(MachineInstr *MI,
   // If the EFLAGS register isn't dead in the terminator, then claim that it's
   // live into the sink and copy blocks.
   if (!MI->killsRegister(X86::EFLAGS)) {
-    copy0MBB->addLiveIn(X86::EFLAGS);
-    sinkMBB->addLiveIn(X86::EFLAGS);
+    if (!shouldHaveEFlagsKill(MI, BB)) {
+      copy0MBB->addLiveIn(X86::EFLAGS);
+      sinkMBB->addLiveIn(X86::EFLAGS);
+    }
   }
 
   // Transfer the remainder of BB and its successor edges to sinkMBB.
index 1dbbdcf892797de823308647b49e98c5d1b9968e..d9f753c7a88e7d97995027516657d13267f651cf 100644 (file)
@@ -6,37 +6,12 @@
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-apple-darwin10.0.0"
 
-; FIXME: This test could generate this code:
-;
-; ## BB#0:                                ## %entry
-;      testq   %rdi, %rdi
-;      jns     LBB0_2
-; ## BB#1:
-;      movq    %rdi, %rax
-;      shrq    %rax
-;      andq    $1, %rdi
-;      orq     %rax, %rdi
-;      cvtsi2ssq       %rdi, %xmm0
-;      addss   %xmm0, %xmm0
-;      ret
-; LBB0_2:                                 ## %entry
-;      cvtsi2ssq       %rdi, %xmm0
-;      ret
-;
-; The blocks come from lowering:
-;
-;   %vreg7<def> = CMOV_FR32 %vreg6<kill>, %vreg5<kill>, 15, %EFLAGS<imp-use>; FR32:%vreg7,%vreg6,%vreg5
-;
-; If the instruction had an EFLAGS<kill> flag, it wouldn't need to mark EFLAGS
-; as live-in on the new blocks, and machine sinking would be able to sink
-; everything below the test.
-
-; CHECK: shrq
-; CHECK: andq
-; CHECK-NEXT: orq
 ; CHECK: testq %rdi, %rdi
 ; CHECK-NEXT: jns LBB0_2
-; CHECK: cvtsi2ss
+; CHECK: shrq
+; CHECK-NEXT: andq
+; CHECK-NEXT: orq
+; CHECK-NEXT: cvtsi2ss
 ; CHECK: LBB0_2
 ; CHECK-NEXT: cvtsi2ss
 define float @test(i64 %a) {