Successfully identified regression in *linux* in CI configuration tcwg_kernel/llvm-master-aarch64-mainline-allyesconfig. So far, this commit has regressed CI configurations:
- tcwg_kernel/llvm-master-aarch64-mainline-allyesconfig
Culprit:
<cut>
commit 342f43af70dbc74f8629381998f92c060e1763a2
Author: Maurizio Lombardi <mlombard(a)redhat.com>
Date: Thu Jul 29 15:52:50 2021 +0200
iscsi_ibft: fix crash due to KASLR physical memory remapping
Starting with commit a799c2bd29d1
("x86/setup: Consolidate early memory reservations")
memory reservations have been moved earlier during the boot process,
before the execution of the Kernel Address Space Layout Randomization code.
setup_arch() calls the iscsi_ibft's find_ibft_region() function
to find and reserve the memory dedicated to the iBFT and this function
also saves a virtual pointer to the iBFT table for later use.
The problem is that if KALSR is active, the physical memory gets
remapped somewhere else in the virtual address space and the pointer is
no longer valid, this will cause a kernel panic when the iscsi driver tries
to dereference it.
iBFT detected.
BUG: unable to handle page fault for address: ffff888000099fd8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] SMP PTI
..snip..
Call Trace:
? ibft_create_kobject+0x1d2/0x1d2 [iscsi_ibft]
do_one_initcall+0x44/0x1d0
? kmem_cache_alloc_trace+0x119/0x220
do_init_module+0x5c/0x270
__do_sys_init_module+0x12e/0x1b0
do_syscall_64+0x40/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
Fix this bug by saving the address of the physical location
of the ibft; later the driver will use isa_bus_to_virt() to get
the correct virtual address.
N.B. On each reboot KASLR randomizes the virtual addresses so
assuming phys_to_virt before KASLR does its deed is incorrect.
Simplify the code by renaming find_ibft_region()
to reserve_ibft_region() and remove all the wrappers.
Signed-off-by: Maurizio Lombardi <mlombard(a)redhat.com>
Reviewed-by: Mike Rapoport <rppt(a)linux.ibm.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad(a)kernel.org>
</cut>
Results regressed to (for first_bad == 342f43af70dbc74f8629381998f92c060e1763a2)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_llvm:
-5
# build_abe qemu:
-2
# linux_n_obj:
19722
# First few build errors in logs:
from (for last_good == 62fb9874f5da54fdb243003b386128037319b219)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_llvm:
-5
# build_abe qemu:
-2
# linux_n_obj:
19795
# linux build successful:
all
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl…
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl…
Build top page/logs: https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-linux-342f43af70dbc74f8629381998f92c060e1763a2
cd investigate-linux-342f43af70dbc74f8629381998f92c060e1763a2
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_kernel-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh)
mkdir -p ./bisect
rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /linux/ ./ ./bisect/baseline/
cd linux
# Reproduce first_bad build
git checkout --detach 342f43af70dbc74f8629381998f92c060e1763a2
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach 62fb9874f5da54fdb243003b386128037319b219
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl…
Build log: https://ci.linaro.org/job/tcwg_kernel-llvm-bisect-llvm-master-aarch64-mainl…
Full commit (up to 1000 lines):
<cut>
commit 342f43af70dbc74f8629381998f92c060e1763a2
Author: Maurizio Lombardi <mlombard(a)redhat.com>
Date: Thu Jul 29 15:52:50 2021 +0200
iscsi_ibft: fix crash due to KASLR physical memory remapping
Starting with commit a799c2bd29d1
("x86/setup: Consolidate early memory reservations")
memory reservations have been moved earlier during the boot process,
before the execution of the Kernel Address Space Layout Randomization code.
setup_arch() calls the iscsi_ibft's find_ibft_region() function
to find and reserve the memory dedicated to the iBFT and this function
also saves a virtual pointer to the iBFT table for later use.
The problem is that if KALSR is active, the physical memory gets
remapped somewhere else in the virtual address space and the pointer is
no longer valid, this will cause a kernel panic when the iscsi driver tries
to dereference it.
iBFT detected.
BUG: unable to handle page fault for address: ffff888000099fd8
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] SMP PTI
..snip..
Call Trace:
? ibft_create_kobject+0x1d2/0x1d2 [iscsi_ibft]
do_one_initcall+0x44/0x1d0
? kmem_cache_alloc_trace+0x119/0x220
do_init_module+0x5c/0x270
__do_sys_init_module+0x12e/0x1b0
do_syscall_64+0x40/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
Fix this bug by saving the address of the physical location
of the ibft; later the driver will use isa_bus_to_virt() to get
the correct virtual address.
N.B. On each reboot KASLR randomizes the virtual addresses so
assuming phys_to_virt before KASLR does its deed is incorrect.
Simplify the code by renaming find_ibft_region()
to reserve_ibft_region() and remove all the wrappers.
Signed-off-by: Maurizio Lombardi <mlombard(a)redhat.com>
Reviewed-by: Mike Rapoport <rppt(a)linux.ibm.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad(a)kernel.org>
---
arch/x86/kernel/setup.c | 10 --------
drivers/firmware/iscsi_ibft.c | 10 +++++---
drivers/firmware/iscsi_ibft_find.c | 48 ++++++++++++++------------------------
include/linux/iscsi_ibft.h | 18 ++++++--------
4 files changed, 32 insertions(+), 54 deletions(-)
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 1e720626069a..b6a62af06a9f 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -571,16 +571,6 @@ void __init reserve_standard_io_resources(void)
}
-static __init void reserve_ibft_region(void)
-{
- unsigned long addr, size = 0;
-
- addr = find_ibft_region(&size);
-
- if (size)
- memblock_reserve(addr, size);
-}
-
static bool __init snb_gfx_workaround_needed(void)
{
#ifdef CONFIG_PCI
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index 7127a04bca19..612a59e213df 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -84,8 +84,10 @@ MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");
MODULE_LICENSE("GPL");
MODULE_VERSION(IBFT_ISCSI_VERSION);
+static struct acpi_table_ibft *ibft_addr;
+
#ifndef CONFIG_ISCSI_IBFT_FIND
-struct acpi_table_ibft *ibft_addr;
+phys_addr_t ibft_phys_addr;
#endif
struct ibft_hdr {
@@ -858,11 +860,13 @@ static int __init ibft_init(void)
int rc = 0;
/*
- As on UEFI systems the setup_arch()/find_ibft_region()
+ As on UEFI systems the setup_arch()/reserve_ibft_region()
is called before ACPI tables are parsed and it only does
legacy finding.
*/
- if (!ibft_addr)
+ if (ibft_phys_addr)
+ ibft_addr = isa_bus_to_virt(ibft_phys_addr);
+ else
acpi_find_ibft_region();
if (ibft_addr) {
diff --git a/drivers/firmware/iscsi_ibft_find.c b/drivers/firmware/iscsi_ibft_find.c
index 64bb94523281..a0594590847d 100644
--- a/drivers/firmware/iscsi_ibft_find.c
+++ b/drivers/firmware/iscsi_ibft_find.c
@@ -31,8 +31,8 @@
/*
* Physical location of iSCSI Boot Format Table.
*/
-struct acpi_table_ibft *ibft_addr;
-EXPORT_SYMBOL_GPL(ibft_addr);
+phys_addr_t ibft_phys_addr;
+EXPORT_SYMBOL_GPL(ibft_phys_addr);
static const struct {
char *sign;
@@ -47,13 +47,24 @@ static const struct {
#define VGA_MEM 0xA0000 /* VGA buffer */
#define VGA_SIZE 0x20000 /* 128kB */
-static int __init find_ibft_in_mem(void)
+/*
+ * Routine used to find and reserve the iSCSI Boot Format Table
+ */
+void __init reserve_ibft_region(void)
{
unsigned long pos;
unsigned int len = 0;
void *virt;
int i;
+ ibft_phys_addr = 0;
+
+ /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
+ * only use ACPI for this
+ */
+ if (efi_enabled(EFI_BOOT))
+ return;
+
for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
/* The table can't be inside the VGA BIOS reserved space,
* so skip that area */
@@ -70,35 +81,12 @@ static int __init find_ibft_in_mem(void)
/* if the length of the table extends past 1M,
* the table cannot be valid. */
if (pos + len <= (IBFT_END-1)) {
- ibft_addr = (struct acpi_table_ibft *)virt;
- pr_info("iBFT found at 0x%lx.\n", pos);
- goto done;
+ ibft_phys_addr = pos;
+ memblock_reserve(ibft_phys_addr, PAGE_ALIGN(len));
+ pr_info("iBFT found at 0x%lx.\n", ibft_phys_addr);
+ return;
}
}
}
}
-done:
- return len;
-}
-/*
- * Routine used to find the iSCSI Boot Format Table. The logical
- * kernel address is set in the ibft_addr global variable.
- */
-unsigned long __init find_ibft_region(unsigned long *sizep)
-{
- ibft_addr = NULL;
-
- /* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
- * only use ACPI for this */
-
- if (!efi_enabled(EFI_BOOT))
- find_ibft_in_mem();
-
- if (ibft_addr) {
- *sizep = PAGE_ALIGN(ibft_addr->header.length);
- return (u64)virt_to_phys(ibft_addr);
- }
-
- *sizep = 0;
- return 0;
}
diff --git a/include/linux/iscsi_ibft.h b/include/linux/iscsi_ibft.h
index b7b45ca82bea..790e7fcfc1a6 100644
--- a/include/linux/iscsi_ibft.h
+++ b/include/linux/iscsi_ibft.h
@@ -13,26 +13,22 @@
#ifndef ISCSI_IBFT_H
#define ISCSI_IBFT_H
-#include <linux/acpi.h>
+#include <linux/types.h>
/*
- * Logical location of iSCSI Boot Format Table.
- * If the value is NULL there is no iBFT on the machine.
+ * Physical location of iSCSI Boot Format Table.
+ * If the value is 0 there is no iBFT on the machine.
*/
-extern struct acpi_table_ibft *ibft_addr;
+extern phys_addr_t ibft_phys_addr;
/*
* Routine used to find and reserve the iSCSI Boot Format Table. The
- * mapped address is set in the ibft_addr variable.
+ * physical address is set in the ibft_phys_addr variable.
*/
#ifdef CONFIG_ISCSI_IBFT_FIND
-unsigned long find_ibft_region(unsigned long *sizep);
+void reserve_ibft_region(void);
#else
-static inline unsigned long find_ibft_region(unsigned long *sizep)
-{
- *sizep = 0;
- return 0;
-}
+static inline void reserve_ibft_region(void) {}
#endif
#endif /* ISCSI_IBFT_H */
</cut>
Successfully identified regression in *llvm* in CI configuration tcwg_bmk_llvm_tx1/llvm-master-aarch64-spec2k6-O3. So far, this commit has regressed CI configurations:
- tcwg_bmk_llvm_tx1/llvm-master-aarch64-spec2k6-O3
Culprit:
<cut>
commit 4cd8dd3fe05e099792e1494dedd074eb5ba289b6
Author: Amy Kwan <amy.kwan1(a)ibm.com>
Date: Sun Aug 22 13:46:52 2021 -0500
[scudo][standalone] Link tests against libatomic if libatomic exists
It is possible that libatomic does not exist on some systems. This patch updates
the scudo standalone tests to link against libatomic if the library exists.
This is an update to the original patch: https://reviews.llvm.org/D64134 and
aims to resolve https://bugs.llvm.org/show_bug.cgi?id=51431.
Differential Revision: https://reviews.llvm.org/D108503
</cut>
Results regressed to (for first_bad == 4cd8dd3fe05e099792e1494dedd074eb5ba289b6)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer:
-5
# build_llvm true:
-3
# true:
0
# benchmark -- -O3 artifacts/build-4cd8dd3fe05e099792e1494dedd074eb5ba289b6/results_id:
1
# 447.dealII,dealII_base.default regressed by 103
from (for last_good == d8d84c9df82fc114f2b22a533a8183065ca1a2e0)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--disable-libsanitizer:
-5
# build_llvm true:
-3
# true:
0
# benchmark -- -O3 artifacts/build-d8d84c9df82fc114f2b22a533a8183065ca1a2e0/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Results ID of last_good: tx1_64/tcwg_bmk_llvm_tx1/bisect-llvm-master-aarch64-spec2k6-O3/4515
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Results ID of first_bad: tx1_64/tcwg_bmk_llvm_tx1/bisect-llvm-master-aarch64-spec2k6-O3/4510
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-llvm-4cd8dd3fe05e099792e1494dedd074eb5ba289b6
cd investigate-llvm-4cd8dd3fe05e099792e1494dedd074eb5ba289b6
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh)
mkdir -p ./bisect
rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /llvm/ ./ ./bisect/baseline/
cd llvm
# Reproduce first_bad build
git checkout --detach 4cd8dd3fe05e099792e1494dedd074eb5ba289b6
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach d8d84c9df82fc114f2b22a533a8183065ca1a2e0
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tx1-llvm-master-…
Full commit (up to 1000 lines):
<cut>
commit 4cd8dd3fe05e099792e1494dedd074eb5ba289b6
Author: Amy Kwan <amy.kwan1(a)ibm.com>
Date: Sun Aug 22 13:46:52 2021 -0500
[scudo][standalone] Link tests against libatomic if libatomic exists
It is possible that libatomic does not exist on some systems. This patch updates
the scudo standalone tests to link against libatomic if the library exists.
This is an update to the original patch: https://reviews.llvm.org/D64134 and
aims to resolve https://bugs.llvm.org/show_bug.cgi?id=51431.
Differential Revision: https://reviews.llvm.org/D108503
---
compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt
index f4186eba1688..eaa47a04a179 100644
--- a/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt
+++ b/compiler-rt/lib/scudo/standalone/tests/CMakeLists.txt
@@ -39,7 +39,10 @@ foreach(lib ${SANITIZER_TEST_CXX_LIBRARIES})
endforeach()
list(APPEND LINK_FLAGS -pthread)
# Linking against libatomic is required with some compilers
-list(APPEND LINK_FLAGS -latomic)
+check_library_exists(atomic __atomic_load_8 "" COMPILER_RT_HAS_LIBATOMIC)
+if (COMPILER_RT_HAS_LIBATOMIC)
+ list(APPEND LINK_FLAGS -latomic)
+endif()
set(SCUDO_TEST_HEADERS
scudo_unit_test.h
</cut>
Progress (short week, 2 days)
* UM-2 [QEMU upstream maintainership]
+ Lots of code review and getting things upstream after trunk reopened
+ Wrote up a first draft of how to handle merging pullreqs, so that
other people can share this job with me
+ Sent a patchset that allows board models to mark some buses as
not suitable for plugging in user-created devices -- this avoids
problems with i2c devices appearing on buses that are supposed to
be for on-board devices only in the MPS2/MPS3 machines
* QEMU-406 [QEMU support for MVE (M-profile Vector Extension; Helium)]
+ MVE is now enabled upstream. (There are still some loose ends to
do under this JIRA task, though.)
+ Sent a patchset that makes some of the easier codegen optimizations
for the no-predication case. (Code review spotted an issue which
might be painful to sort out -- we'll see next week...)
-- PMM
Successfully identified regression in *binutils* in CI configuration tcwg_bmk_llvm_apm/llvm-master-arm-spec2k6-Oz. So far, this commit has regressed CI configurations:
- tcwg_bmk_llvm_apm/llvm-master-arm-spec2k6-Oz
Culprit:
<cut>
commit 590d3faada8a12bf0937bbf68413956dc6a339a9
Author: Tom de Vries <tdevries(a)suse.de>
Date: Mon Aug 30 10:30:26 2021 +0200
[gdb/testsuite] Improve argument syntax of proc arange
The current syntax of proc arange is:
...
proc arange { arange_start arange_length {comment ""} {seg_sel ""} } {
...
and a typical call looks like:
...
arange $start $len
...
This style is somewhat annoying because if you want to specify the last
parameter, you need to give the default values of all the other optional ones
before as well:
...
arange $start $len "" $seg_sel
...
Update the syntax to:
...
proc arange { options arange_start arange_length } {
parse_options {
{ comment "" }
{ seg_sel "" }
}
...
such that a typical call looks like:
...
arange {} $start $len
...
and a call using seg_sel looks like:
...
arange {
seg_sel $seg_sel
} $start $len
...
Also update proc aranges, which already has an options argument, to use the
new proc parse_options.
Tested on x86_64-linux.
Co-Authored-By: Simon Marchi <simon.marchi(a)polymtl.ca>
</cut>
Results regressed to (for first_bad == 590d3faada8a12bf0937bbf68413956dc6a339a9)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--with-mode=thumb --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--with-mode=thumb --set gcc_override_configure=--disable-libsanitizer:
-5
# build_llvm true:
-3
# true:
0
# benchmark -- -Oz_mthumb artifacts/build-590d3faada8a12bf0937bbf68413956dc6a339a9/results_id:
1
# 447.dealII,[.] contract<3> regressed by 200
from (for last_good == cb03dd22b36b7bd21a81137005ec42dab8355b62)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--with-mode=thumb --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--with-mode=thumb --set gcc_override_configure=--disable-libsanitizer:
-5
# build_llvm true:
-3
# true:
0
# benchmark -- -Oz_mthumb artifacts/build-cb03dd22b36b7bd21a81137005ec42dab8355b62/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-…
Results ID of last_good: apm_32/tcwg_bmk_llvm_apm/bisect-llvm-master-arm-spec2k6-Oz/4418
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-…
Results ID of first_bad: apm_32/tcwg_bmk_llvm_apm/bisect-llvm-master-arm-spec2k6-Oz/4431
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-binutils-590d3faada8a12bf0937bbf68413956dc6a339a9
cd investigate-binutils-590d3faada8a12bf0937bbf68413956dc6a339a9
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_bmk-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh)
mkdir -p ./bisect
rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /binutils/ ./ ./bisect/baseline/
cd binutils
# Reproduce first_bad build
git checkout --detach 590d3faada8a12bf0937bbf68413956dc6a339a9
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach cb03dd22b36b7bd21a81137005ec42dab8355b62
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_apm-llvm-master-…
Full commit (up to 1000 lines):
<cut>
commit 590d3faada8a12bf0937bbf68413956dc6a339a9
Author: Tom de Vries <tdevries(a)suse.de>
Date: Mon Aug 30 10:30:26 2021 +0200
[gdb/testsuite] Improve argument syntax of proc arange
The current syntax of proc arange is:
...
proc arange { arange_start arange_length {comment ""} {seg_sel ""} } {
...
and a typical call looks like:
...
arange $start $len
...
This style is somewhat annoying because if you want to specify the last
parameter, you need to give the default values of all the other optional ones
before as well:
...
arange $start $len "" $seg_sel
...
Update the syntax to:
...
proc arange { options arange_start arange_length } {
parse_options {
{ comment "" }
{ seg_sel "" }
}
...
such that a typical call looks like:
...
arange {} $start $len
...
and a call using seg_sel looks like:
...
arange {
seg_sel $seg_sel
} $start $len
...
Also update proc aranges, which already has an options argument, to use the
new proc parse_options.
Tested on x86_64-linux.
Co-Authored-By: Simon Marchi <simon.marchi(a)polymtl.ca>
---
gdb/testsuite/gdb.dlang/watch-loc.exp | 2 +-
gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp | 6 +-
.../gdb.dwarf2/frame-inlined-in-outer-frame.exp | 2 +-
.../template-specification-full-name.exp | 2 +-
gdb/testsuite/gdb.testsuite/parse_options_args.exp | 59 ++++++++++++
gdb/testsuite/lib/dwarf.exp | 31 +++---
gdb/testsuite/lib/gdb.exp | 104 ++++++++++++++-------
7 files changed, 150 insertions(+), 56 deletions(-)
diff --git a/gdb/testsuite/gdb.dlang/watch-loc.exp b/gdb/testsuite/gdb.dlang/watch-loc.exp
index 6e8b26e3109..e13400ed479 100644
--- a/gdb/testsuite/gdb.dlang/watch-loc.exp
+++ b/gdb/testsuite/gdb.dlang/watch-loc.exp
@@ -68,7 +68,7 @@ Dwarf::assemble $asm_file {
}
aranges {} cu_start {
- arange $dmain_start $dmain_length
+ arange {} $dmain_start $dmain_length
}
}
diff --git a/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp b/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp
index e65b4c8610a..d55b7fd150e 100644
--- a/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp
+++ b/gdb/testsuite/gdb.dwarf2/dw2-ranges-base.exp
@@ -125,9 +125,9 @@ Dwarf::assemble $asm_file {
}
aranges {} cu_label {
- arange [lindex $main_func 0] [lindex $main_func 1]
- arange [lindex $frame2_func 0] [lindex $frame2_func 1]
- arange [lindex $frame3_func 0] [lindex $frame3_func 1]
+ arange {} [lindex $main_func 0] [lindex $main_func 1]
+ arange {} [lindex $frame2_func 0] [lindex $frame2_func 1]
+ arange {} [lindex $frame3_func 0] [lindex $frame3_func 1]
}
}
diff --git a/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp b/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp
index ff12cd79f19..f95558dffef 100644
--- a/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp
+++ b/gdb/testsuite/gdb.dwarf2/frame-inlined-in-outer-frame.exp
@@ -95,7 +95,7 @@ Dwarf::assemble $dwarf_asm {
}
aranges {} cu_label {
- arange __cu_low_pc __cu_high_pc
+ arange {} __cu_low_pc __cu_high_pc
}
}
diff --git a/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp b/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp
index 5c59777e1b6..6e736f2c8ef 100644
--- a/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp
+++ b/gdb/testsuite/gdb.dwarf2/template-specification-full-name.exp
@@ -69,7 +69,7 @@ Dwarf::assemble $asm_file {
}
aranges {} cu_start {
- arange "$main_start" "$main_length"
+ arange {} "$main_start" "$main_length"
}
}
diff --git a/gdb/testsuite/gdb.testsuite/parse_options_args.exp b/gdb/testsuite/gdb.testsuite/parse_options_args.exp
new file mode 100644
index 00000000000..ce14fc3cd7c
--- /dev/null
+++ b/gdb/testsuite/gdb.testsuite/parse_options_args.exp
@@ -0,0 +1,59 @@
+# Copyright 2021 Free Software Foundation, Inc.
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Testsuite self-tests for parse_options and parse_args.
+
+with_test_prefix parse_options {
+ proc test1 { options a b } {
+ set v2 "defval2"
+ parse_options {
+ { opt1 defval1 }
+ { opt2 $v2 }
+ { opt3 }
+ { opt4 }
+ }
+
+ gdb_assert { [string equal $a "vala"] }
+ gdb_assert { [string equal $b "valb"] }
+ gdb_assert { [string equal $opt1 "val1"] }
+ gdb_assert { [string equal $opt2 "defval2"] }
+ gdb_assert { $opt3 == 1 }
+ gdb_assert { $opt4 == 0 }
+ }
+
+ set v1 "val1"
+ test1 { opt1 $v1 opt3 } "vala" "valb"
+}
+
+with_test_prefix parse_args {
+ proc test2 { args } {
+ parse_args {
+ { opt1 defval1 }
+ { opt2 defval2 }
+ { opt3 }
+ { opt4 }
+ }
+ gdb_assert { [llength $args] == 2 }
+ lassign $args a b
+ gdb_assert { [string equal $a "vala"] }
+ gdb_assert { [string equal $b "valb"] }
+ gdb_assert { [string equal $opt1 "val1"] }
+ gdb_assert { [string equal $opt2 "defval2"] }
+ gdb_assert { $opt3 == 1 }
+ gdb_assert { $opt4 == 0 }
+ }
+
+ set v1 "val1"
+ test2 -opt1 $v1 -opt3 "vala" "valb"
+}
diff --git a/gdb/testsuite/lib/dwarf.exp b/gdb/testsuite/lib/dwarf.exp
index 120fa418201..7fb3561a443 100644
--- a/gdb/testsuite/lib/dwarf.exp
+++ b/gdb/testsuite/lib/dwarf.exp
@@ -2212,7 +2212,12 @@ namespace eval Dwarf {
# Emit a DWARF .debug_aranges entry.
- proc arange { arange_start arange_length {comment ""} {seg_sel ""} } {
+ proc arange { options arange_start arange_length } {
+ parse_options {
+ { comment "" }
+ { seg_sel "" }
+ }
+
if { $comment != "" } {
# Wrap
set comment " ($comment)"
@@ -2270,22 +2275,14 @@ namespace eval Dwarf {
variable _addr_size
variable _seg_size
- # Establish the defaults.
- set is_64 0
- set cu_is_64 0
- set section_version 2
- set _seg_size 0
-
# Handle options.
- foreach { name value } $options {
- switch -exact -- $name {
- is_64 { set is_64 $value }
- cu_is_64 { set cu_is_64 $value }
- section_version {set section_version $value }
- seg_size { set _seg_size $value }
- default { error "unknown option $name" }
- }
+ parse_options {
+ { is_64 0 }
+ { cu_is_64 0 }
+ { section_version 2 }
+ { seg_size 0 }
}
+ set _seg_size $seg_size
if { [is_64_target] } {
set _addr_size 8
@@ -2354,9 +2351,9 @@ namespace eval Dwarf {
# Terminator tuple.
set comment "Terminator"
if { $_seg_size == 0 } {
- arange 0 0 $comment
+ arange {comment $comment} 0 0
} else {
- arange 0 0 $comment 0
+ arange {comment $comment seg_sel 0} 0 0
}
# End label.
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index 093392709b4..3aea7baaab0 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -7293,8 +7293,8 @@ proc using_fission { } {
return [regexp -- "-gsplit-dwarf" $debug_flags]
}
-# Search the caller's ARGS list and set variables according to the list of
-# valid options described by ARGSET.
+# Search LISTNAME in uplevel LEVEL caller and set variables according to the
+# list of valid options with prefix PREFIX described by ARGSET.
#
# The first member of each one- or two-element list in ARGSET defines the
# name of a variable that will be added to the caller's scope.
@@ -7305,13 +7305,15 @@ proc using_fission { } {
#
# If two elements are given, the second element is the default value of
# the variable. This is then overwritten if the option exists in ARGS.
+# If EVAL, then subst is called on the value, which allows variables
+# to be used.
#
# Any parse_args elements in (the caller's) ARGS will be removed, leaving
# any optional components.
-
+#
# Example:
# proc myproc {foo args} {
-# parse_args {{bar} {baz "abc"} {qux}}
+# parse_list args 1 {{bar} {baz "abc"} {qux}} "-" false
# # ...
# }
# myproc ABC -bar -baz DEF peanut butter
@@ -7319,43 +7321,79 @@ proc using_fission { } {
# foo (=ABC), bar (=1), baz (=DEF), and qux (=0)
# args will be the list {peanut butter}
-proc parse_args { argset } {
- upvar args args
+proc parse_list { level listname argset prefix eval } {
+ upvar $level $listname args
foreach argument $argset {
- if {[llength $argument] == 1} {
- # No default specified, so we assume that we should set
- # the value to 1 if the arg is present and 0 if it's not.
- # It is assumed that no value is given with the argument.
- set result [lsearch -exact $args "-$argument"]
- if {$result != -1} then {
- uplevel 1 [list set $argument 1]
- set args [lreplace $args $result $result]
- } else {
- uplevel 1 [list set $argument 0]
- }
- } elseif {[llength $argument] == 2} {
- # There are two items in the argument. The second is a
- # default value to use if the item is not present.
- # Otherwise, the variable is set to whatever is provided
- # after the item in the args.
- set arg [lindex $argument 0]
- set result [lsearch -exact $args "-[lindex $arg 0]"]
- if {$result != -1} then {
- uplevel 1 [list set $arg [lindex $args [expr $result+1]]]
- set args [lreplace $args $result [expr $result+1]]
- } else {
- uplevel 1 [list set $arg [lindex $argument 1]]
- }
- } else {
- error "Badly formatted argument \"$argument\" in argument set"
- }
+ if {[llength $argument] == 1} {
+ # Normalize argument, strip leading/trailing whitespace.
+ # Allows us to treat {foo} and { foo } the same.
+ set argument [string trim $argument]
+
+ # No default specified, so we assume that we should set
+ # the value to 1 if the arg is present and 0 if it's not.
+ # It is assumed that no value is given with the argument.
+ set pattern "$prefix$argument"
+ set result [lsearch -exact $args $pattern]
+
+ if {$result != -1} then {
+ set value 1
+ set args [lreplace $args $result $result]
+ } else {
+ set value 0
+ }
+ uplevel $level [list set $argument $value]
+ } elseif {[llength $argument] == 2} {
+ # There are two items in the argument. The second is a
+ # default value to use if the item is not present.
+ # Otherwise, the variable is set to whatever is provided
+ # after the item in the args.
+ set arg [lindex $argument 0]
+ set pattern "$prefix[lindex $arg 0]"
+ set result [lsearch -exact $args $pattern]
+
+ if {$result != -1} then {
+ set value [lindex $args [expr $result+1]]
+ if { $eval } {
+ set value [uplevel [expr $level + 1] [list subst $value]]
+ }
+ set args [lreplace $args $result [expr $result+1]]
+ } else {
+ set value [lindex $argument 1]
+ if { $eval } {
+ set value [uplevel $level [list subst $value]]
+ }
+ }
+ uplevel $level [list set $arg $value]
+ } else {
+ error "Badly formatted argument \"$argument\" in argument set"
+ }
}
+}
+
+# Search the caller's args variable and set variables according to the list of
+# valid options described by ARGSET.
+
+proc parse_args { argset } {
+ parse_list 2 args $argset "-" false
# The remaining args should be checked to see that they match the
# number of items expected to be passed into the procedure...
}
+# Process the caller's options variable and set variables according
+# to the list of valid options described by OPTIONSET.
+
+proc parse_options { optionset } {
+ parse_list 2 options $optionset "" true
+
+ # Require no remaining options.
+ upvar 1 options options
+ if { [llength $options] != 0 } {
+ error "Options left unparsed: $options"
+ }
+}
+
# Capture the output of COMMAND in a string ignoring PREFIX (a regexp);
# return that string.
</cut>
Successfully identified regression in *gcc* in CI configuration tcwg_gcc_bootstrap/master-arm-bootstrap_O3. So far, this commit has regressed CI configurations:
- tcwg_gcc_bootstrap/master-arm-bootstrap_O3
Culprit:
<cut>
commit cad36f38576a6a781e3c62ab061c68f5b8dab13a
Author: Roger Sayle <roger(a)nextmovesoftware.com>
Date: Tue Aug 31 11:45:07 2021 +0100
Preserve SUBREG_PROMOTED_VAR_P on (extend:HI (subreg/s:QI (reg:SI))).
SUBREG_PROMOTED_VAR_P is a mechanism for tracking that a partial subreg
is correctly zero-extended or sign-extended in the parent register. For
example, the RTL (subreg/s/v:QI (reg/v:SI 23 [ x ]) 0) indicates that the
byte x is zero extended in reg:SI 23, which is useful for optimization.
An example is that zero extending the above QImode value to HImode can
simply use a wider subreg, i.e. (subreg:HI (reg/v:SI 23 [ x ]) 0).
This patch addresses the oversight/missed optimization opportunity that
the new HImode subreg above should retain its SUBREG_PROMOTED_VAR_P
annotation as its value is guaranteed to be correctly extended in the
SImode parent. The code below to preserve SUBREG_PROMOTED_VAR_P is already
present in the middle-end (e.g. simplify-rtx.c:7232-7242) but missing
from one or two (precisely three) places that (accidentally) strip it.
Whilst there I also added another optimization. If we need to extend
the above QImode value beyond the SImode register holding it, say to
DImode, we can eliminate the SUBREG and simply extend from the SImode
register to DImode.
2021-08-31 Roger Sayle <roger(a)nextmovesoftware.com>
gcc/ChangeLog
* expr.c (convert_modes): Preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg.
* simplify-rtx.c (simplify_unary_operation_1) [SIGN_EXTEND]:
Likewise, preserve SUBREG_PROMOTED_VAR_P when creating a (wider)
partial subreg from a SUBREG_PROMOTED_VAR_P subreg. Generate
SIGN_EXTEND of the SUBREG_REG when a subreg would be paradoxical.
[ZERO_EXTEND]: Likewise, preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg. Generate ZERO_EXTEND of the SUBREG_REG when a subreg
would be paradoxical.
</cut>
Results regressed to (for first_bad == cad36f38576a6a781e3c62ab061c68f5b8dab13a)
# reset_artifacts:
-10
# true:
0
# build_abe binutils:
1
# First few build errors in logs:
from (for last_good == 0960d937d9bee3c831d0b64a9c828c263a58ff89)
# reset_artifacts:
-10
# true:
0
# build_abe binutils:
1
# build_abe bootstrap_O3:
2
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3…
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3…
Build top page/logs: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-cad36f38576a6a781e3c62ab061c68f5b8dab13a
cd investigate-gcc-cad36f38576a6a781e3c62ab061c68f5b8dab13a
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_gnu-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh)
mkdir -p ./bisect
rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /gcc/ ./ ./bisect/baseline/
cd gcc
# Reproduce first_bad build
git checkout --detach cad36f38576a6a781e3c62ab061c68f5b8dab13a
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach 0960d937d9bee3c831d0b64a9c828c263a58ff89
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3…
Build log: https://ci.linaro.org/job/tcwg_gcc_bootstrap-bisect-master-arm-bootstrap_O3…
Full commit (up to 1000 lines):
<cut>
commit cad36f38576a6a781e3c62ab061c68f5b8dab13a
Author: Roger Sayle <roger(a)nextmovesoftware.com>
Date: Tue Aug 31 11:45:07 2021 +0100
Preserve SUBREG_PROMOTED_VAR_P on (extend:HI (subreg/s:QI (reg:SI))).
SUBREG_PROMOTED_VAR_P is a mechanism for tracking that a partial subreg
is correctly zero-extended or sign-extended in the parent register. For
example, the RTL (subreg/s/v:QI (reg/v:SI 23 [ x ]) 0) indicates that the
byte x is zero extended in reg:SI 23, which is useful for optimization.
An example is that zero extending the above QImode value to HImode can
simply use a wider subreg, i.e. (subreg:HI (reg/v:SI 23 [ x ]) 0).
This patch addresses the oversight/missed optimization opportunity that
the new HImode subreg above should retain its SUBREG_PROMOTED_VAR_P
annotation as its value is guaranteed to be correctly extended in the
SImode parent. The code below to preserve SUBREG_PROMOTED_VAR_P is already
present in the middle-end (e.g. simplify-rtx.c:7232-7242) but missing
from one or two (precisely three) places that (accidentally) strip it.
Whilst there I also added another optimization. If we need to extend
the above QImode value beyond the SImode register holding it, say to
DImode, we can eliminate the SUBREG and simply extend from the SImode
register to DImode.
2021-08-31 Roger Sayle <roger(a)nextmovesoftware.com>
gcc/ChangeLog
* expr.c (convert_modes): Preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg.
* simplify-rtx.c (simplify_unary_operation_1) [SIGN_EXTEND]:
Likewise, preserve SUBREG_PROMOTED_VAR_P when creating a (wider)
partial subreg from a SUBREG_PROMOTED_VAR_P subreg. Generate
SIGN_EXTEND of the SUBREG_REG when a subreg would be paradoxical.
[ZERO_EXTEND]: Likewise, preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg. Generate ZERO_EXTEND of the SUBREG_REG when a subreg
would be paradoxical.
---
gcc/expr.c | 19 ++++++++++++++++++-
gcc/simplify-rtx.c | 52 ++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 60 insertions(+), 11 deletions(-)
diff --git a/gcc/expr.c b/gcc/expr.c
index 096c0315ecc..5dd98a9bccc 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -688,7 +688,24 @@ convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
&& (GET_MODE_PRECISION (subreg_promoted_mode (x))
>= GET_MODE_PRECISION (int_mode))
&& SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
- x = gen_lowpart (int_mode, SUBREG_REG (x));
+ {
+ scalar_int_mode int_orig_mode;
+ machine_mode orig_mode = GET_MODE (x);
+ x = gen_lowpart (int_mode, SUBREG_REG (x));
+
+ /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
+ the original mode, but narrower than the inner mode. */
+ if (GET_CODE (x) == SUBREG
+ && GET_MODE_PRECISION (subreg_promoted_mode (x))
+ > GET_MODE_PRECISION (int_mode)
+ && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
+ && GET_MODE_PRECISION (int_mode)
+ > GET_MODE_PRECISION (int_orig_mode))
+ {
+ SUBREG_PROMOTED_VAR_P (x) = 1;
+ SUBREG_PROMOTED_SET (x, unsignedp);
+ }
+ }
if (GET_MODE (x) != VOIDmode)
oldmode = GET_MODE (x);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index e431e0c19d7..ebad5cb5a79 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1512,12 +1512,28 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
target mode is the same as the variable's promotion. */
if (GET_CODE (op) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op)
- && SUBREG_PROMOTED_SIGNED_P (op)
- && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
+ && SUBREG_PROMOTED_SIGNED_P (op))
{
- temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
- if (temp)
- return temp;
+ rtx subreg = SUBREG_REG (op);
+ machine_mode subreg_mode = GET_MODE (subreg);
+ if (!paradoxical_subreg_p (mode, subreg_mode))
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
+ if (temp)
+ {
+ /* Preserve SUBREG_PROMOTED_VAR_P. */
+ if (partial_subreg_p (temp))
+ {
+ SUBREG_PROMOTED_VAR_P (temp) = 1;
+ SUBREG_PROMOTED_SET (temp, 1);
+ }
+ return temp;
+ }
+ }
+ else
+ /* Sign-extending a sign-extended subreg. */
+ return simplify_gen_unary (SIGN_EXTEND, mode,
+ subreg, subreg_mode);
}
/* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
@@ -1631,12 +1647,28 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
target mode is the same as the variable's promotion. */
if (GET_CODE (op) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op)
- && SUBREG_PROMOTED_UNSIGNED_P (op)
- && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
+ && SUBREG_PROMOTED_UNSIGNED_P (op))
{
- temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
- if (temp)
- return temp;
+ rtx subreg = SUBREG_REG (op);
+ machine_mode subreg_mode = GET_MODE (subreg);
+ if (!paradoxical_subreg_p (mode, subreg_mode))
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
+ if (temp)
+ {
+ /* Preserve SUBREG_PROMOTED_VAR_P. */
+ if (partial_subreg_p (temp))
+ {
+ SUBREG_PROMOTED_VAR_P (temp) = 1;
+ SUBREG_PROMOTED_SET (temp, 0);
+ }
+ return temp;
+ }
+ }
+ else
+ /* Zero-extending a zero-extended subreg. */
+ return simplify_gen_unary (ZERO_EXTEND, mode,
+ subreg, subreg_mode);
}
/* Extending a widening multiplication should be canonicalized to
</cut>
Successfully identified regression in *gcc* in CI configuration tcwg_gnu_native_build/master-aarch64. So far, this commit has regressed CI configurations:
- tcwg_gnu_native_build/master-aarch64
Culprit:
<cut>
commit cad36f38576a6a781e3c62ab061c68f5b8dab13a
Author: Roger Sayle <roger(a)nextmovesoftware.com>
Date: Tue Aug 31 11:45:07 2021 +0100
Preserve SUBREG_PROMOTED_VAR_P on (extend:HI (subreg/s:QI (reg:SI))).
SUBREG_PROMOTED_VAR_P is a mechanism for tracking that a partial subreg
is correctly zero-extended or sign-extended in the parent register. For
example, the RTL (subreg/s/v:QI (reg/v:SI 23 [ x ]) 0) indicates that the
byte x is zero extended in reg:SI 23, which is useful for optimization.
An example is that zero extending the above QImode value to HImode can
simply use a wider subreg, i.e. (subreg:HI (reg/v:SI 23 [ x ]) 0).
This patch addresses the oversight/missed optimization opportunity that
the new HImode subreg above should retain its SUBREG_PROMOTED_VAR_P
annotation as its value is guaranteed to be correctly extended in the
SImode parent. The code below to preserve SUBREG_PROMOTED_VAR_P is already
present in the middle-end (e.g. simplify-rtx.c:7232-7242) but missing
from one or two (precisely three) places that (accidentally) strip it.
Whilst there I also added another optimization. If we need to extend
the above QImode value beyond the SImode register holding it, say to
DImode, we can eliminate the SUBREG and simply extend from the SImode
register to DImode.
2021-08-31 Roger Sayle <roger(a)nextmovesoftware.com>
gcc/ChangeLog
* expr.c (convert_modes): Preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg.
* simplify-rtx.c (simplify_unary_operation_1) [SIGN_EXTEND]:
Likewise, preserve SUBREG_PROMOTED_VAR_P when creating a (wider)
partial subreg from a SUBREG_PROMOTED_VAR_P subreg. Generate
SIGN_EXTEND of the SUBREG_REG when a subreg would be paradoxical.
[ZERO_EXTEND]: Likewise, preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg. Generate ZERO_EXTEND of the SUBREG_REG when a subreg
would be paradoxical.
</cut>
Results regressed to (for first_bad == cad36f38576a6a781e3c62ab061c68f5b8dab13a)
# reset_artifacts:
-10
# true:
0
# build_abe binutils:
1
# First few build errors in logs:
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-2.h:249:37: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-2.h:249:37: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-2.h:249:37: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-1.h:127:36: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-1.h:127:36: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-2.h:249:37: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-2.h:249:37: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-1.h:127:36: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 /home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/soft-fp/op-2.h:249:37: internal compiler error: in subreg_promoted_mode, at rtl.h:3132
# 00:05:59 make[2]: *** [/home/tcwg-buildslave/workspace/tcwg_gnu_6/abe/snapshots/gcc.git~master/libgcc/shared-object.mk:14: trunctfhf2.o] Error 1
from (for last_good == 0960d937d9bee3c831d0b64a9c828c263a58ff89)
# reset_artifacts:
-10
# true:
0
# build_abe binutils:
1
# build_abe gcc:
2
# build_abe linux:
4
# build_abe glibc:
5
# build_abe gdb:
6
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/art…
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/art…
Build top page/logs: https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-cad36f38576a6a781e3c62ab061c68f5b8dab13a
cd investigate-gcc-cad36f38576a6a781e3c62ab061c68f5b8dab13a
git clone https://git.linaro.org/toolchain/jenkins-scripts
mkdir -p artifacts/manifests
curl -o artifacts/manifests/build-baseline.sh https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/art… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/art… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/art… --fail
chmod +x artifacts/test.sh
# Reproduce the baseline build (build all pre-requisites)
./jenkins-scripts/tcwg_gnu-build.sh @@ artifacts/manifests/build-baseline.sh
# Save baseline build state (which is then restored in artifacts/test.sh)
mkdir -p ./bisect
rsync -a --del --delete-excluded --exclude /bisect/ --exclude /artifacts/ --exclude /gcc/ ./ ./bisect/baseline/
cd gcc
# Reproduce first_bad build
git checkout --detach cad36f38576a6a781e3c62ab061c68f5b8dab13a
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach 0960d937d9bee3c831d0b64a9c828c263a58ff89
../artifacts/test.sh
cd ..
</cut>
History of pending regressions and results: https://git.linaro.org/toolchain/ci/base-artifacts.git/log/?h=linaro-local/…
Artifacts: https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/art…
Build log: https://ci.linaro.org/job/tcwg_gnu_native_build-bisect-master-aarch64/1/con…
Full commit (up to 1000 lines):
<cut>
commit cad36f38576a6a781e3c62ab061c68f5b8dab13a
Author: Roger Sayle <roger(a)nextmovesoftware.com>
Date: Tue Aug 31 11:45:07 2021 +0100
Preserve SUBREG_PROMOTED_VAR_P on (extend:HI (subreg/s:QI (reg:SI))).
SUBREG_PROMOTED_VAR_P is a mechanism for tracking that a partial subreg
is correctly zero-extended or sign-extended in the parent register. For
example, the RTL (subreg/s/v:QI (reg/v:SI 23 [ x ]) 0) indicates that the
byte x is zero extended in reg:SI 23, which is useful for optimization.
An example is that zero extending the above QImode value to HImode can
simply use a wider subreg, i.e. (subreg:HI (reg/v:SI 23 [ x ]) 0).
This patch addresses the oversight/missed optimization opportunity that
the new HImode subreg above should retain its SUBREG_PROMOTED_VAR_P
annotation as its value is guaranteed to be correctly extended in the
SImode parent. The code below to preserve SUBREG_PROMOTED_VAR_P is already
present in the middle-end (e.g. simplify-rtx.c:7232-7242) but missing
from one or two (precisely three) places that (accidentally) strip it.
Whilst there I also added another optimization. If we need to extend
the above QImode value beyond the SImode register holding it, say to
DImode, we can eliminate the SUBREG and simply extend from the SImode
register to DImode.
2021-08-31 Roger Sayle <roger(a)nextmovesoftware.com>
gcc/ChangeLog
* expr.c (convert_modes): Preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg.
* simplify-rtx.c (simplify_unary_operation_1) [SIGN_EXTEND]:
Likewise, preserve SUBREG_PROMOTED_VAR_P when creating a (wider)
partial subreg from a SUBREG_PROMOTED_VAR_P subreg. Generate
SIGN_EXTEND of the SUBREG_REG when a subreg would be paradoxical.
[ZERO_EXTEND]: Likewise, preserve SUBREG_PROMOTED_VAR_P when
creating a (wider) partial subreg from a SUBREG_PROMOTED_VAR_P
subreg. Generate ZERO_EXTEND of the SUBREG_REG when a subreg
would be paradoxical.
---
gcc/expr.c | 19 ++++++++++++++++++-
gcc/simplify-rtx.c | 52 ++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 60 insertions(+), 11 deletions(-)
diff --git a/gcc/expr.c b/gcc/expr.c
index 096c0315ecc..5dd98a9bccc 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -688,7 +688,24 @@ convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
&& (GET_MODE_PRECISION (subreg_promoted_mode (x))
>= GET_MODE_PRECISION (int_mode))
&& SUBREG_CHECK_PROMOTED_SIGN (x, unsignedp))
- x = gen_lowpart (int_mode, SUBREG_REG (x));
+ {
+ scalar_int_mode int_orig_mode;
+ machine_mode orig_mode = GET_MODE (x);
+ x = gen_lowpart (int_mode, SUBREG_REG (x));
+
+ /* Preserve SUBREG_PROMOTED_VAR_P if the new mode is wider than
+ the original mode, but narrower than the inner mode. */
+ if (GET_CODE (x) == SUBREG
+ && GET_MODE_PRECISION (subreg_promoted_mode (x))
+ > GET_MODE_PRECISION (int_mode)
+ && is_a <scalar_int_mode> (orig_mode, &int_orig_mode)
+ && GET_MODE_PRECISION (int_mode)
+ > GET_MODE_PRECISION (int_orig_mode))
+ {
+ SUBREG_PROMOTED_VAR_P (x) = 1;
+ SUBREG_PROMOTED_SET (x, unsignedp);
+ }
+ }
if (GET_MODE (x) != VOIDmode)
oldmode = GET_MODE (x);
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index e431e0c19d7..ebad5cb5a79 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -1512,12 +1512,28 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
target mode is the same as the variable's promotion. */
if (GET_CODE (op) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op)
- && SUBREG_PROMOTED_SIGNED_P (op)
- && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
+ && SUBREG_PROMOTED_SIGNED_P (op))
{
- temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
- if (temp)
- return temp;
+ rtx subreg = SUBREG_REG (op);
+ machine_mode subreg_mode = GET_MODE (subreg);
+ if (!paradoxical_subreg_p (mode, subreg_mode))
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
+ if (temp)
+ {
+ /* Preserve SUBREG_PROMOTED_VAR_P. */
+ if (partial_subreg_p (temp))
+ {
+ SUBREG_PROMOTED_VAR_P (temp) = 1;
+ SUBREG_PROMOTED_SET (temp, 1);
+ }
+ return temp;
+ }
+ }
+ else
+ /* Sign-extending a sign-extended subreg. */
+ return simplify_gen_unary (SIGN_EXTEND, mode,
+ subreg, subreg_mode);
}
/* (sign_extend:M (sign_extend:N <X>)) is (sign_extend:M <X>).
@@ -1631,12 +1647,28 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode,
target mode is the same as the variable's promotion. */
if (GET_CODE (op) == SUBREG
&& SUBREG_PROMOTED_VAR_P (op)
- && SUBREG_PROMOTED_UNSIGNED_P (op)
- && !paradoxical_subreg_p (mode, GET_MODE (SUBREG_REG (op))))
+ && SUBREG_PROMOTED_UNSIGNED_P (op))
{
- temp = rtl_hooks.gen_lowpart_no_emit (mode, SUBREG_REG (op));
- if (temp)
- return temp;
+ rtx subreg = SUBREG_REG (op);
+ machine_mode subreg_mode = GET_MODE (subreg);
+ if (!paradoxical_subreg_p (mode, subreg_mode))
+ {
+ temp = rtl_hooks.gen_lowpart_no_emit (mode, subreg);
+ if (temp)
+ {
+ /* Preserve SUBREG_PROMOTED_VAR_P. */
+ if (partial_subreg_p (temp))
+ {
+ SUBREG_PROMOTED_VAR_P (temp) = 1;
+ SUBREG_PROMOTED_SET (temp, 0);
+ }
+ return temp;
+ }
+ }
+ else
+ /* Zero-extending a zero-extended subreg. */
+ return simplify_gen_unary (ZERO_EXTEND, mode,
+ subreg, subreg_mode);
}
/* Extending a widening multiplication should be canonicalized to
</cut>