[PR] Fix ShrinkWrapping pop order

Summary:
The push and pop instructions might have wrong reorder due to this
error. Thanks rafaelauler for the provided test case.

Vladislav Khmelevsky,
Advanced Software Technology Lab, Huawei

(cherry picked from FBD32478348)
This commit is contained in:
Vladislav Khmelevsky 2021-11-14 02:23:20 +03:00 committed by Maksim Panchenko
parent 68b0003ee3
commit a944a487ae
2 changed files with 47 additions and 2 deletions

View File

@ -1852,9 +1852,9 @@ BBIterTy ShrinkWrapping::processInsertionsList(
(B.Action != WorklistItem::InsertPushOrPop || !B.FIEToInsert.IsLoad))
return false;
if ((A.Action != WorklistItem::InsertPushOrPop || !A.FIEToInsert.IsLoad))
return false;
if ((B.Action != WorklistItem::InsertPushOrPop || !B.FIEToInsert.IsLoad))
return true;
if ((B.Action != WorklistItem::InsertPushOrPop || !B.FIEToInsert.IsLoad))
return false;
return DomOrder[B.AffectedReg] < DomOrder[A.AffectedReg];
});

View File

@ -0,0 +1,45 @@
# This test reproduces a POP reordering issue in shrink wrapping where we would
# incorrectly put a store after a load (instead of before) when having multiple
# insertions at the same point. Check that the order is correct in this test.
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
# RUN: link_fdata %s %t.o %t.fdata
# RUN: llvm-strip --strip-unneeded %t.o
# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
# RUN: llvm-bolt %t.exe -o %t.out -data %t.fdata -frame-opt=all -lite=0 \
# RUN: -print-fop 2>&1 | FileCheck %s
.globl _start
_start:
.cfi_startproc
# FDATA: 0 [unknown] 0 1 _start 0 0 6
je a
b: jne _start
# FDATA: 1 _start #b# 1 _start #c# 0 3
c:
push %rbx
push %rbp
pop %rbp
pop %rbx
# This basic block is treated as having 0 execution count.
# push and pop will be sinked into this block.
a:
ud2
.cfi_endproc
# Check shrink wrapping results:
# CHECK: BOLT-INFO: Shrink wrapping moved 0 spills inserting load/stores and 2 spills inserting push/pops
# Check that order is correct
# CHECK: Binary Function "_start" after frame-optimizer
# Pushes are ordered according to their reg number and come first
# CHECK: pushq %rbp
# CHECK: pushq %rbx
# Pops are ordered according to their dominance relation and come last
# CHECK: popq %rbx
# CHECK: popq %rbp