[llvm] 7550f14 - [X86] Clear kill flags when rewriting SETCC uses in flag copy lowering.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 21 14:29:53 PDT 2021


Author: Craig Topper
Date: 2021-09-21T14:29:46-07:00
New Revision: 7550f146ff75667d6e1828d64438dcc23b77f036

URL: https://github.com/llvm/llvm-project/commit/7550f146ff75667d6e1828d64438dcc23b77f036
DIFF: https://github.com/llvm/llvm-project/commit/7550f146ff75667d6e1828d64438dcc23b77f036.diff

LOG: [X86] Clear kill flags when rewriting SETCC uses in flag copy lowering.

When we rewrite the setcc we replace set old setcc output register
with the new CondReg. But since CondReg can be shared by other
replacements, we don't know if the kill flags for the old register
are valid for CondReg. So be conservative and remove them.

The test case has a SETCCr and a SETCCm on the same condition so
they end up sharing the same CondReg. The SETCCr had one use with
a kill flag. This kill flag isn't valid after the replacement because
CondReg needs a live range extending to the later SETCCm replacment.

Fixes PR51908.

Reviewed By: RKSimon

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

Added: 
    llvm/test/CodeGen/X86/pr51908.mir

Modified: 
    llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
    llvm/test/CodeGen/X86/flags-copy-lowering.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
index 2d9886e3f238c..f24dbcfe972df 100644
--- a/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
+++ b/llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
@@ -964,7 +964,11 @@ void X86FlagsCopyLoweringPass::rewriteSetCC(MachineBasicBlock &TestMBB,
   if (!SetCCI.mayStore()) {
     assert(SetCCI.getOperand(0).isReg() &&
            "Cannot have a non-register defined operand to SETcc!");
-    MRI->replaceRegWith(SetCCI.getOperand(0).getReg(), CondReg);
+    Register OldReg = SetCCI.getOperand(0).getReg();
+    // Drop Kill flags on the old register before replacing. CondReg may have
+    // a longer live range.
+    MRI->clearKillFlags(OldReg);
+    MRI->replaceRegWith(OldReg, CondReg);
     SetCCI.eraseFromParent();
     return;
   }

diff  --git a/llvm/test/CodeGen/X86/flags-copy-lowering.mir b/llvm/test/CodeGen/X86/flags-copy-lowering.mir
index dfb5f7d5e2ff9..069afd030ac53 100644
--- a/llvm/test/CodeGen/X86/flags-copy-lowering.mir
+++ b/llvm/test/CodeGen/X86/flags-copy-lowering.mir
@@ -250,10 +250,10 @@ body:             |
     MOV8mr $rsp, 1, $noreg, -16, $noreg, killed %5
   ; CHECK-NOT:     $eflags =
   ; CHECK-NOT:             = SET{{.*}}
-  ; CHECK:         MOV8mr {{.*}}, killed %[[A_REG]]
-  ; CHECK-NEXT:    MOV8mr {{.*}}, killed %[[B_REG]]
-  ; CHECK-NEXT:    MOV8mr {{.*}}, killed %[[E_REG]]
-  ; CHECK-NOT:     MOV8mr {{.*}}, killed %[[NE_REG]]
+  ; CHECK:         MOV8mr {{.*}}, %[[A_REG]]
+  ; CHECK-NEXT:    MOV8mr {{.*}}, %[[B_REG]]
+  ; CHECK-NEXT:    MOV8mr {{.*}}, %[[E_REG]]
+  ; CHECK-NOT:     MOV8mr {{.*}}, %[[NE_REG]]
 
     RET 0
 

diff  --git a/llvm/test/CodeGen/X86/pr51908.mir b/llvm/test/CodeGen/X86/pr51908.mir
new file mode 100644
index 0000000000000..f9d0416874a4c
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr51908.mir
@@ -0,0 +1,108 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc %s -o - -mtriple=x86_64-unknown-linux-gnu -run-pass=x86-flags-copy-lowering -verify-machineinstrs | FileCheck %s
+
+--- |
+  ; ModuleID = 'bugpoint-reduced-simplified.ll'
+  source_filename = "test.c"
+  target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+  target triple = "x86_64-unknown-linux-gnu"
+
+  @a = external global i32, align 4
+
+  declare void @e()
+
+  define void @f() {
+  entry:
+    br label %for.body
+
+  for.body:                                         ; preds = %for.body, %entry
+    %0 = load i32, i32* @a, align 4
+    %conv = sext i32 %0 to i64
+    %1 = load i64, i64* undef, align 8
+    %or = or i64 %1, %conv
+    store i64 %or, i64* undef, align 8
+    call void @e()
+    %cmp4 = icmp eq i64 %or, 0
+    %conv5 = zext i1 %cmp4 to i32
+    %conv6 = trunc i32 %conv5 to i8
+    store i8 %conv6, i8* undef, align 1
+    %conv7 = sext i8 %conv6 to i32
+    %bf.cast = trunc i40 undef to i32
+    %xor = xor i32 %conv7, %bf.cast
+    %conv8 = sext i32 %xor to i64
+    store i64 %conv8, i64* undef, align 8
+    br label %for.body
+  }
+
+...
+---
+name:            f
+alignment:       16
+tracksRegLiveness: true
+registers:
+  - { id: 0, class: gr64 }
+  - { id: 1, class: gr64 }
+  - { id: 2, class: gr32 }
+  - { id: 3, class: gr64 }
+  - { id: 4, class: gr32 }
+  - { id: 5, class: gr32 }
+  - { id: 6, class: gr32 }
+  - { id: 7, class: gr64 }
+  - { id: 8, class: gr64 }
+  - { id: 9, class: gr64 }
+  - { id: 10, class: gr64 }
+  - { id: 11, class: gr8 }
+  - { id: 12, class: gr64 }
+frameInfo:
+  maxAlignment:    1
+  hasCalls:        true
+machineFunctionInfo: {}
+body:             |
+  ; CHECK-LABEL: name: f
+  ; CHECK: bb.0.entry:
+  ; CHECK:   successors: %bb.1(0x80000000)
+  ; CHECK:   JMP_1 %bb.1
+  ; CHECK: bb.1.for.body:
+  ; CHECK:   successors: %bb.1(0x80000000)
+  ; CHECK:   [[MOV64rm:%[0-9]+]]:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @a, $noreg :: (load (s64) from got)
+  ; CHECK:   [[MOVSX64rm32_:%[0-9]+]]:gr64 = MOVSX64rm32 killed [[MOV64rm]], 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from @a)
+  ; CHECK:   [[DEF:%[0-9]+]]:gr64 = IMPLICIT_DEF
+  ; CHECK:   OR64mr [[DEF]], 1, $noreg, 0, $noreg, [[MOVSX64rm32_]], implicit-def $eflags :: (store (s64) into `i64* undef`), (load (s64) from `i64* undef`)
+  ; CHECK:   [[SETCCr:%[0-9]+]]:gr8 = SETCCr 4, implicit $eflags
+  ; CHECK:   ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+  ; CHECK:   CALL64pcrel32 target-flags(x86-plt) @e, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp
+  ; CHECK:   ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+  ; CHECK:   [[MOVZX32rr8_:%[0-9]+]]:gr32 = MOVZX32rr8 [[SETCCr]]
+  ; CHECK:   [[DEF1:%[0-9]+]]:gr64 = IMPLICIT_DEF
+  ; CHECK:   MOV8mr [[DEF1]], 1, $noreg, 0, $noreg, [[SETCCr]] :: (store (s8) into `i8* undef`)
+  ; CHECK:   [[DEF2:%[0-9]+]]:gr32 = IMPLICIT_DEF
+  ; CHECK:   [[XOR32rr:%[0-9]+]]:gr32 = XOR32rr [[MOVZX32rr8_]], [[DEF2]], implicit-def $eflags
+  ; CHECK:   [[MOVSX64rr32_:%[0-9]+]]:gr64 = MOVSX64rr32 [[XOR32rr]]
+  ; CHECK:   [[DEF3:%[0-9]+]]:gr64 = IMPLICIT_DEF
+  ; CHECK:   MOV64mr [[DEF3]], 1, $noreg, 0, $noreg, [[MOVSX64rr32_]] :: (store (s64) into `i64* undef`)
+  ; CHECK:   JMP_1 %bb.1
+  bb.0.entry:
+    JMP_1 %bb.1
+
+  bb.1.for.body:
+    %7:gr64 = MOV64rm $rip, 1, $noreg, target-flags(x86-gotpcrel) @a, $noreg :: (load (s64) from got)
+    %8:gr64 = MOVSX64rm32 killed %7, 1, $noreg, 0, $noreg :: (dereferenceable load (s32) from @a)
+    %9:gr64 = IMPLICIT_DEF
+    OR64mr %9, 1, $noreg, 0, $noreg, %8, implicit-def $eflags :: (store (s64) into `i64* undef`), (load (s64) from `i64* undef`)
+    %10:gr64 = COPY $eflags
+    ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+    CALL64pcrel32 target-flags(x86-plt) @e, csr_64, implicit $rsp, implicit $ssp, implicit-def $rsp, implicit-def $ssp
+    ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp
+    $eflags = COPY %10
+    %11:gr8 = SETCCr 4, implicit $eflags
+    %4:gr32 = MOVZX32rr8 killed %11
+    %12:gr64 = IMPLICIT_DEF
+    SETCCm %12, 1, $noreg, 0, $noreg, 4, implicit $eflags :: (store (s8) into `i8* undef`)
+    %5:gr32 = IMPLICIT_DEF
+    %6:gr32 = XOR32rr %4, %5, implicit-def $eflags
+    %3:gr64 = MOVSX64rr32 %6
+    %0:gr64 = IMPLICIT_DEF
+    MOV64mr %0, 1, $noreg, 0, $noreg, %3 :: (store (s64) into `i64* undef`)
+    JMP_1 %bb.1
+
+...


        


More information about the llvm-commits mailing list