[VirtRegRewriter] Properly model the register liveness on undef subreg definition
Undef subreg definition means that the content of the super register
doesn't matter at this point. While that's true for virtual registers,
this may not hold when replacing them with actual physical registers.
Indeed, some part of the physical register may be coalesced with the
related virtual register and thus, the values for those parts matter and
must be live.
The fix consists in checking whether or not subregs of the physical register
being assigned to an undef subreg definition are live through that def and
insert an implicit use if they are. Doing so, will keep them alive until
that point like they should be.
E.g., let vreg14 being assigned to R0_R1 then
%vreg14:gsub_0<def,read-undef> = COPY %R0 ; <-- R1 is still live here
%vreg14:gsub_1<def> = COPY %R1
Before this changes, the rewriter would change the code into:
%R0<def> = KILL %R0, %R0_R1<imp-def> ; <-- this tells R1 is redefined
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use> ; this value of this R1
; is believed to come
; from the previous
; instruction
Because of this invalid liveness, later pass could make wrong choices and in
particular clobber live register as it happened with the register scavenger in
llvm.org/PR34107
Now we would generate:
%R0<def> = KILL %R0, %R0_R1<imp-def>, %R0_R1<imp-use> ; This tells R1 needs to
; reach this point
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use>
The bug has been here forever, it got exposed recently because the register
scavenger got smarter.
Fixes llvm.org/PR34107
llvm-svn: 310979
2017-08-16 08:17:05 +08:00
|
|
|
# RUN: llc -o - -mtriple=thumbv7--windows-gnu -run-pass=greedy -run-pass=virtregrewriter %s | FileCheck %s
|
|
|
|
--- |
|
|
|
|
target datalayout = "e-m:w-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
|
|
|
|
target triple = "thumbv7--windows-gnu"
|
|
|
|
|
|
|
|
define void @subregLiveThrough() { ret void }
|
|
|
|
define void @subregNotLiveThrough() { ret void }
|
|
|
|
define void @subregNotLiveThrough2() { ret void }
|
|
|
|
|
|
|
|
...
|
|
|
|
---
|
|
|
|
# Check that we properly recognize that r1 is live through
|
|
|
|
# the first subreg copy.
|
|
|
|
# That will materialize as an implicit use of the big register
|
|
|
|
# on that copy.
|
|
|
|
# PR34107.
|
|
|
|
#
|
|
|
|
# CHECK-LABEL: name: subregLiveThrough
|
|
|
|
name: subregLiveThrough
|
|
|
|
tracksRegLiveness: true
|
|
|
|
registers:
|
|
|
|
- { id: 0, class: gprpair }
|
|
|
|
body: |
|
|
|
|
bb.0:
|
|
|
|
liveins: %r0, %r1
|
|
|
|
|
|
|
|
; That copy is being coalesced so we should use a KILL
|
|
|
|
; placeholder. If that's not a kill that means we probably
|
|
|
|
; not coalescing %0 and %r0_r1 and thus we are not testing
|
|
|
|
; the problematic code anymore.
|
|
|
|
;
|
|
|
|
; CHECK: %r0 = KILL %r0, implicit killed %r0_r1, implicit-def %r0_r1
|
|
|
|
; CHECK-NEXT: %r1 = KILL %r1, implicit killed %r0_r1
|
|
|
|
undef %0.gsub_0 = COPY %r0
|
|
|
|
%0.gsub_1 = COPY %r1
|
2017-12-01 00:12:24 +08:00
|
|
|
tBX_RET 14, %noreg, implicit %0
|
[VirtRegRewriter] Properly model the register liveness on undef subreg definition
Undef subreg definition means that the content of the super register
doesn't matter at this point. While that's true for virtual registers,
this may not hold when replacing them with actual physical registers.
Indeed, some part of the physical register may be coalesced with the
related virtual register and thus, the values for those parts matter and
must be live.
The fix consists in checking whether or not subregs of the physical register
being assigned to an undef subreg definition are live through that def and
insert an implicit use if they are. Doing so, will keep them alive until
that point like they should be.
E.g., let vreg14 being assigned to R0_R1 then
%vreg14:gsub_0<def,read-undef> = COPY %R0 ; <-- R1 is still live here
%vreg14:gsub_1<def> = COPY %R1
Before this changes, the rewriter would change the code into:
%R0<def> = KILL %R0, %R0_R1<imp-def> ; <-- this tells R1 is redefined
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use> ; this value of this R1
; is believed to come
; from the previous
; instruction
Because of this invalid liveness, later pass could make wrong choices and in
particular clobber live register as it happened with the register scavenger in
llvm.org/PR34107
Now we would generate:
%R0<def> = KILL %R0, %R0_R1<imp-def>, %R0_R1<imp-use> ; This tells R1 needs to
; reach this point
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use>
The bug has been here forever, it got exposed recently because the register
scavenger got smarter.
Fixes llvm.org/PR34107
llvm-svn: 310979
2017-08-16 08:17:05 +08:00
|
|
|
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
---
|
|
|
|
# Check that we properly recognize that r1 is *not* live through
|
|
|
|
# the first subreg copy.
|
|
|
|
# CHECK-LABEL: name: subregNotLiveThrough
|
|
|
|
name: subregNotLiveThrough
|
|
|
|
tracksRegLiveness: true
|
|
|
|
registers:
|
|
|
|
- { id: 0, class: gprpair }
|
|
|
|
body: |
|
|
|
|
bb.0:
|
|
|
|
liveins: %r0, %r1
|
|
|
|
|
|
|
|
; r1 is not live through so check we are not implicitly using
|
|
|
|
; the big register.
|
|
|
|
; CHECK: %r0 = KILL %r0, implicit-def %r0_r1
|
|
|
|
; CHECK-NEXT: tBX_RET
|
|
|
|
undef %0.gsub_0 = COPY %r0
|
2017-12-01 00:12:24 +08:00
|
|
|
tBX_RET 14, %noreg, implicit %0
|
[VirtRegRewriter] Properly model the register liveness on undef subreg definition
Undef subreg definition means that the content of the super register
doesn't matter at this point. While that's true for virtual registers,
this may not hold when replacing them with actual physical registers.
Indeed, some part of the physical register may be coalesced with the
related virtual register and thus, the values for those parts matter and
must be live.
The fix consists in checking whether or not subregs of the physical register
being assigned to an undef subreg definition are live through that def and
insert an implicit use if they are. Doing so, will keep them alive until
that point like they should be.
E.g., let vreg14 being assigned to R0_R1 then
%vreg14:gsub_0<def,read-undef> = COPY %R0 ; <-- R1 is still live here
%vreg14:gsub_1<def> = COPY %R1
Before this changes, the rewriter would change the code into:
%R0<def> = KILL %R0, %R0_R1<imp-def> ; <-- this tells R1 is redefined
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use> ; this value of this R1
; is believed to come
; from the previous
; instruction
Because of this invalid liveness, later pass could make wrong choices and in
particular clobber live register as it happened with the register scavenger in
llvm.org/PR34107
Now we would generate:
%R0<def> = KILL %R0, %R0_R1<imp-def>, %R0_R1<imp-use> ; This tells R1 needs to
; reach this point
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use>
The bug has been here forever, it got exposed recently because the register
scavenger got smarter.
Fixes llvm.org/PR34107
llvm-svn: 310979
2017-08-16 08:17:05 +08:00
|
|
|
|
|
|
|
|
|
|
|
...
|
|
|
|
|
|
|
|
---
|
|
|
|
# Check that we properly recognize that r1 is *not* live through
|
|
|
|
# the first subreg copy. It is defined by this copy, but is not
|
|
|
|
# through.
|
|
|
|
# CHECK-LABEL: name: subregNotLiveThrough2
|
|
|
|
name: subregNotLiveThrough2
|
|
|
|
tracksRegLiveness: true
|
|
|
|
registers:
|
|
|
|
- { id: 0, class: gprpair }
|
|
|
|
body: |
|
|
|
|
bb.0:
|
|
|
|
liveins: %r0, %r1
|
|
|
|
|
|
|
|
; r1 is not live through so check we are not implicitly using
|
|
|
|
; the big register.
|
|
|
|
; CHECK: %r0 = KILL %r0, implicit-def %r1, implicit-def %r0_r1
|
|
|
|
; CHECK-NEXT: tBX_RET
|
|
|
|
undef %0.gsub_0 = COPY %r0, implicit-def %r1
|
2017-12-01 00:12:24 +08:00
|
|
|
tBX_RET 14, %noreg, implicit %0
|
[VirtRegRewriter] Properly model the register liveness on undef subreg definition
Undef subreg definition means that the content of the super register
doesn't matter at this point. While that's true for virtual registers,
this may not hold when replacing them with actual physical registers.
Indeed, some part of the physical register may be coalesced with the
related virtual register and thus, the values for those parts matter and
must be live.
The fix consists in checking whether or not subregs of the physical register
being assigned to an undef subreg definition are live through that def and
insert an implicit use if they are. Doing so, will keep them alive until
that point like they should be.
E.g., let vreg14 being assigned to R0_R1 then
%vreg14:gsub_0<def,read-undef> = COPY %R0 ; <-- R1 is still live here
%vreg14:gsub_1<def> = COPY %R1
Before this changes, the rewriter would change the code into:
%R0<def> = KILL %R0, %R0_R1<imp-def> ; <-- this tells R1 is redefined
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use> ; this value of this R1
; is believed to come
; from the previous
; instruction
Because of this invalid liveness, later pass could make wrong choices and in
particular clobber live register as it happened with the register scavenger in
llvm.org/PR34107
Now we would generate:
%R0<def> = KILL %R0, %R0_R1<imp-def>, %R0_R1<imp-use> ; This tells R1 needs to
; reach this point
%R1<def> = KILL %R1, %R0_R1<imp-def>, %R0_R1<imp-use>
The bug has been here forever, it got exposed recently because the register
scavenger got smarter.
Fixes llvm.org/PR34107
llvm-svn: 310979
2017-08-16 08:17:05 +08:00
|
|
|
|
|
|
|
|
|
|
|
...
|