Craig Topper b81e26c7f4 Recommit "[X86] Clear kill flags when rewriting SETCC uses in flag copy lowering."
This time with the right bug number.

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 PR51903.
2021-09-21 14:59:25 -07:00

109 lines
4.6 KiB
YAML

# 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
...