Successfully identified regression in *gcc* in CI configuration tcwg_gnu/gnu-master-arm-check_bootstrap. So far, this commit has regressed CI configurations:
- tcwg_gnu/gnu-master-arm-check_bootstrap
Culprit:
<cut>
commit 7d8211603a3d04384812b481b0ae01205a287a72
Author: Richard Biener <rguenther(a)suse.de>
Date: Wed Jun 30 16:28:50 2021 +0200
tree-optimization/101178 - handle VEC_PERM in SLP permute propagation
This adds handling of VEC_PERM nodes to SLP permute propagation.
Previously VEC_PERM acted as forced materialization of incoming
permutes since it is a good place to do that (with the constraint
of those only appearing for two-operator nodes). The following
patch, in addition to supporting (but not forcing) this, enables
VEC_PERM nodes acting as "any" permute on the outgoing side since
they also can consume arbitrary permutes on that side.
This again (meh) changes how we represent permutes and materialization
on the graph vertices now explicitely having the common incoming
permute as well as an outgoing permute and in case both are
different the vertex acts as materialization point of the incoming
permute.
2021-06-30 Richard Biener <rguenther(a)suse.de>
PR tree-optimization/101178
* tree-vect-slp.c (slpg_vertex::materialize): Remove.
(slpg::perm_in): Add.
(slpg::get_perm_in): Remove.
(slpg::get_perm_materialized): Add.
(vect_optimize_slp): Handle VEC_PERM nodes more optimally
during permute propagation and materialization.
* gcc.dg/vect/bb-slp-72.c: New testcase.
* gcc.dg/vect/bb-slp-73.c: Likewise.
* gcc.dg/vect/bb-slp-74.c: Likewise.
</cut>
Results regressed to (for first_bad == 7d8211603a3d04384812b481b0ae01205a287a72)
# reset_artifacts:
-10
# build_abe bootstrap:
0
# build_abe check_bootstrap:
1
# # Comparing directories
# # REFERENCE: base-artifacts/sumfiles
# # CURRENT: /home/tcwg-buildslave/workspace/tcwg_gnu_2/artifacts/build-7d8211603a3d04384812b481b0ae01205a287a72/sumfiles
#
# # Comparing 12 common sum files:
# g++.sum
# gcc.sum
# gfortran.sum
# go.sum
# gotools.sum
# libatomic.sum
# libffi.sum
# libgo.sum
# libgomp.sum
# libitm.sum
# libstdc++.sum
# objc.sum
# Comparing:
# REFERENCE:/tmp/gxx-sum1.3498108
# CURRENT: /tmp/gxx-sum2.3498108
#
# ` +---------+---------+
# o RUN STATUS: | REF | RES |
# +------------------------------------------+---------+---------+
# | Passes [PASS] | 460520 | 460704 |
# | Unexpected fails [FAIL] | 196 | 195 |
# | Errors [ERROR] | 0 | 0 |
# | Unexpected passes [XPASS] | 15 | 15 |
# | Expected fails [XFAIL] | 2737 | 2723 |
# | Unresolved [UNRESOLVED] | 104 | 104 |
# | Unsupported [UNSUPPORTED] | 22896 | 22903 |
# | Untested [UNTESTED] | 10 | 10 |
# +------------------------------------------+---------+---------+
#
# REF PASS ratio: 0.952267
# RES PASS ratio: 0.952272
#
# o REGRESSIONS:
# +------------------------------------------+---------+
# | FAIL appears [ => FAIL] | 2 |
# +------------------------------------------+---------+
# | TOTAL_REGRESSIONS | 2 |
# +------------------------------------------+---------+
#
# - FAIL appears [ => FAIL]:
#
# Executed from: gcc.dg/vect/vect.exp
# gcc:gcc.dg/vect/bb-slp-74.c -flto -ffat-lto-objects scan-tree-dump-times slp2 " [^ ]+ = VEC_PERM_EXPR" 1
# gcc:gcc.dg/vect/bb-slp-74.c scan-tree-dump-times slp2 " [^ ]+ = VEC_PERM_EXPR" 1
#
#
#
# o IMPROVEMENTS TO BE CHECKED:
# +------------------------------------------+---------+
# | PASS disappears [PASS => ] | 114 |
# | New PASS [ => PASS] | 296 |
# | FAIL now PASS [FAIL => PASS] | 2 |
# | FAIL disappears [FAIL => ] | 1 |
# | XFAIL disappears [XFAIL=> ] | 17 |
# | XFAIL appears [ =>XFAIL] | 3 |
# | UNSUPPORTED appears [ =>UNSUP] | 7 |
# +------------------------------------------+---------+
# | TOTAL_IMPROVEMENTS_TO_BE_CHECKED | 440 |
# +------------------------------------------+---------+
#
# - PASS disappears [PASS => ]:
#
# Executed from: g++.dg/dg.exp
# g++:g++.dg/cpp0x/auto24.C -std=c++14 (test for errors, line 5)
# g++:g++.dg/cpp0x/auto24.C -std=c++17 (test for errors, line 5)
# g++:g++.dg/cpp0x/auto24.C -std=c++2a (test for errors, line 5)
# g++:g++.dg/diagnostic/auto1.C -std=c++17 (test for errors, line 4)
# g++:g++.dg/diagnostic/auto1.C -std=c++2a (test for errors, line 4)
# Executed from: gcc.dg/analyzer/analyzer.exp
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1007)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1009)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1010)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1013)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1018)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1025)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1026)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 510)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 518)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 519)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 539)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 540)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 557)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 559)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 562)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 565)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 566)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 570)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 573)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 574)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 578)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 579)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 581)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 582)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 586)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 587)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 604)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 606)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 609)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 612)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 613)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 617)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 620)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 621)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 628)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 629)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 632)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 635)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 636)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 654)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 656)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 659)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 662)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 663)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 667)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 670)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 671)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 676)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 678)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 679)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 682)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 684)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 685)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 703)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 705)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 708)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 711)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 712)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 716)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 719)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 720)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 725)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 727)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 728)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 731)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 733)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 744)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 745)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 765)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 769)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 770)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 781)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 787)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 795)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 800)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 801)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 812)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 816)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 842)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 850)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 870)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 873)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 875)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 895)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 908)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 909)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 914)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 923)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 932)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 947)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 950)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 965)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 968)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 1038)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 506)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 511)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 525)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 528)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 532)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 535)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 63)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 67)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 68)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 77)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 81)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 82)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 98)
# Executed from: libstdc++-dg/conformance.exp
# libstdc++:26_numerics/random/pr60037-neg.cc (test for errors, line 167)
# libstdc++:26_numerics/random/pr60037-neg.cc (test for errors, line 3346)
#
#
# - New PASS [ => PASS]:
#
# Executed from: g++.dg/dg.exp
# g++:g++.dg/cpp0x/constexpr-empty16.C -std=c++14 (test for excess errors)
# g++:g++.dg/cpp0x/constexpr-empty16.C -std=c++17 (test for excess errors)
# g++:g++.dg/cpp0x/constexpr-empty16.C -std=c++2a (test for excess errors)
# g++:g++.dg/cpp23/auto-array.C -std=c++14 (test for excess errors)
# g++:g++.dg/cpp23/auto-array.C -std=c++17 (test for excess errors)
# g++:g++.dg/cpp23/auto-array.C -std=c++2a (test for excess errors)
# g++:g++.dg/cpp2a/concepts-access2.C -std=c++2a (test for errors, line 13)
# g++:g++.dg/cpp2a/concepts-access2.C -std=c++2a (test for errors, line 4)
# g++:g++.dg/cpp2a/concepts-access2.C -std=c++2a (test for excess errors)
# g++:g++.dg/template/access41.C -std=c++14 (test for excess errors)
# g++:g++.dg/template/access41.C -std=c++17 (test for excess errors)
# g++:g++.dg/template/access41.C -std=c++2a (test for excess errors)
# g++:g++.dg/template/access41a.C -std=c++14 (test for excess errors)
# g++:g++.dg/template/access41a.C -std=c++17 (test for excess errors)
# g++:g++.dg/template/access41a.C -std=c++2a (test for excess errors)
# Executed from: gcc.misc-tests/help.exp
# gcc:compiler driver --help=common option(s): ^ +-.*[^:.]$
# Executed from: gcc.dg/analyzer/analyzer.exp
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 22)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 24)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 25)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 33)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 35)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 36)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 44)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 46)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 47)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 54)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 55)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 67)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 68)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 69)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 70)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 71)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 72)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 73)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 74)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 88)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 89)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 90)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 91)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 92)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 93)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 94)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 95)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 96)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for warnings, line 97)
# gcc:gcc.dg/analyzer/clobbers-1.c (test for excess errors)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 11)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 12)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 13)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 14)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 15)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 19)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 20)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 21)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 22)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 23)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 24)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 31)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 32)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 33)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 37)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 38)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 39)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 40)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 47)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 48)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 49)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 53)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 54)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 55)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 56)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 63)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 64)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 68)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 69)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 70)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for warnings, line 71)
# gcc:gcc.dg/analyzer/clobbers-2.c (test for excess errors)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1000)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1003)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1015)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1028)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 1029)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 506)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 508)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 516)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 517)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 523)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 524)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 526)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 527)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 529)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 530)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 546)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 547)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 549)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 550)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 552)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 553)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 555)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 561)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 564)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 568)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 569)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 572)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 576)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 577)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 593)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 594)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 596)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 597)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 599)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 600)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 602)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 608)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 611)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 615)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 616)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 619)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 622)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 643)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 644)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 646)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 647)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 649)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 650)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 652)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 658)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 661)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 665)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 666)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 669)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 672)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 674)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 692)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 693)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 695)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 696)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 698)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 699)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 701)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 707)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 710)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 714)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 715)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 718)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 721)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 723)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 735)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 755)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 759)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 760)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 767)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 771)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 785)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 790)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 791)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 802)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 806)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 832)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 840)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 860)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 863)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 865)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 885)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 898)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 899)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 903)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 904)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 922)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 937)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 940)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 955)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 958)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 996)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 997)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 998)
# gcc:gcc.dg/analyzer/data-model-1.c (test for warnings, line 999)
# gcc:gcc.dg/analyzer/data-model-1.c status quo (test for warnings, line 509)
# gcc:gcc.dg/analyzer/explode-1.c (test for warnings, line 15)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 100)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 110)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 111)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 112)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 126)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 127)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 128)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 129)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 130)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 131)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 132)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 133)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 134)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 135)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 136)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 137)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 138)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 139)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 140)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 141)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 142)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 143)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 144)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 145)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 154)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 155)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 156)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 157)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 158)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 159)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 160)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 161)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 164)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 165)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 166)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 167)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 168)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 169)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 170)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 171)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 174)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 175)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 176)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 177)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 178)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 179)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 180)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 181)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 184)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 185)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 186)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 187)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 188)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 189)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 190)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 191)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 194)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 195)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 196)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 197)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 198)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 199)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 200)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 201)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 39)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 48)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 57)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 61)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 62)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 71)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 75)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 76)
# gcc:gcc.dg/analyzer/memset-1.c (test for warnings, line 92)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 100)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 101)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 102)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 103)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 104)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 105)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 106)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 62)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 63)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 64)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 65)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 66)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 67)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 68)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 71)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 72)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 98)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for warnings, line 99)
# gcc:gcc.dg/analyzer/memset-CVE-2017-18549-1.c (test for excess errors)
# gcc:gcc.dg/analyzer/symbolic-8.c (test for excess errors)
# Executed from: gcc.dg/dg.exp
# gcc:gcc.dg/pr101254.c (test for excess errors)
# gcc:gcc.dg/pr101254.c execution test
# gcc:gcc.dg/pr101266.c (test for excess errors)
# Executed from: gcc.dg/vect/vect.exp
# gcc:gcc.dg/vect/bb-slp-72.c (test for excess errors)
# gcc:gcc.dg/vect/bb-slp-72.c -flto -ffat-lto-objects (test for excess errors)
# gcc:gcc.dg/vect/bb-slp-72.c -flto -ffat-lto-objects execution test
# gcc:gcc.dg/vect/bb-slp-72.c execution test
# gcc:gcc.dg/vect/bb-slp-73.c (test for excess errors)
# gcc:gcc.dg/vect/bb-slp-73.c -flto -ffat-lto-objects (test for excess errors)
# gcc:gcc.dg/vect/bb-slp-73.c -flto -ffat-lto-objects execution test
# gcc:gcc.dg/vect/bb-slp-73.c execution test
# gcc:gcc.dg/vect/bb-slp-74.c (test for excess errors)
# gcc:gcc.dg/vect/bb-slp-74.c -flto -ffat-lto-objects (test for excess errors)
# gcc:gcc.dg/vect/bb-slp-74.c -flto -ffat-lto-objects execution test
# gcc:gcc.dg/vect/bb-slp-74.c execution test
# Executed from: gfortran.dg/dg.exp
# gfortran:gfortran.dg/pr101264.f90 -O (test for excess errors)
# gfortran:gfortran.dg/pr101267.f90 -O (test for excess errors)
# Executed from: libgomp.c++/c++.exp
# libgomp:libgomp.c++/../libgomp.c-c++-common/pr94366.c (test for excess errors)
# libgomp:libgomp.c++/../libgomp.c-c++-common/pr94366.c execution test
# Executed from: libgomp.c/c.exp
# libgomp:libgomp.c/../libgomp.c-c++-common/pr94366.c (test for excess errors)
# libgomp:libgomp.c/../libgomp.c-c++-common/pr94366.c execution test
# Executed from: libstdc++-dg/conformance.exp
# libstdc++:26_numerics/random/pr60037-neg.cc (test for errors, line 166)
# libstdc++:26_numerics/random/pr60037-neg.cc (test for errors, line 3350)
#
#
# - FAIL now PASS [FAIL => PASS]:
#
# Executed from: gcc.dg/debug/ctf/ctf.exp
# gcc:gcc.dg/debug/ctf/ctf-skip-types-2.c (test for excess errors)
# Executed from: go.test/go-test.exp
# go:go.test/test/fixedbugs/issue19182.go execution, -O2 -g
#
#
# - FAIL disappears [FAIL => ]:
#
# Executed from: gcc.misc-tests/help.exp
# gcc:compiler driver --help=common option(s): "^ +-.*[^:.]$" absent from output: " -foffload=<targets>=<options> Specify options for the offloading targets"
#
#
# - XFAIL disappears [XFAIL=> ]:
#
# Executed from: gcc.dg/analyzer/analyzer.exp
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 1038)
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 506)
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 511)
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 525)
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 528)
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 532)
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 535)
# gcc:gcc.dg/analyzer/data-model-1.c uninit-warning-removed (test for warnings, line 824)
# gcc:gcc.dg/analyzer/data-model-1.c uninit-warning-removed (test for warnings, line 832)
# gcc:gcc.dg/analyzer/memset-1.c known nonzero (test for warnings, line 110)
# gcc:gcc.dg/analyzer/memset-1.c known nonzero (test for warnings, line 112)
# gcc:gcc.dg/analyzer/memset-1.c known nonzero (test for warnings, line 41)
# gcc:gcc.dg/analyzer/memset-1.c known nonzero (test for warnings, line 53)
# gcc:gcc.dg/analyzer/memset-1.c status quo (test for bogus messages, line 110)
# gcc:gcc.dg/analyzer/memset-1.c status quo (test for bogus messages, line 112)
# gcc:gcc.dg/analyzer/memset-1.c status quo (test for bogus messages, line 41)
# gcc:gcc.dg/analyzer/memset-1.c status quo (test for bogus messages, line 53)
#
#
# - XFAIL appears [ =>XFAIL]:
#
# Executed from: gcc.dg/analyzer/analyzer.exp
# gcc:gcc.dg/analyzer/data-model-1.c desired (test for warnings, line 509)
# gcc:gcc.dg/analyzer/data-model-1.c uninit-warning-removed (test for warnings, line 814)
# gcc:gcc.dg/analyzer/data-model-1.c uninit-warning-removed (test for warnings, line 822)
#
#
# - UNSUPPORTED appears [ =>UNSUP]:
#
# Executed from: g++.dg/dg.exp
# g++:g++.dg/cpp0x/constexpr-empty16.C -std=c++98
# g++:g++.dg/cpp23/auto-array.C -std=c++98
# g++:g++.dg/cpp2a/concepts-access2.C -std=c++14
# g++:g++.dg/cpp2a/concepts-access2.C -std=c++17
# g++:g++.dg/cpp2a/concepts-access2.C -std=c++98
# g++:g++.dg/template/access41.C -std=c++98
# g++:g++.dg/template/access41a.C -std=c++98
#
#
#
# # Regressions found
# # Regressions in 12 common sum files found
from (for last_good == b0ab968999c9af88d45acf552ca673ef3960306a)
# reset_artifacts:
-10
# build_abe bootstrap:
0
# build_abe check_bootstrap:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/73…
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/73…
Build top page/logs: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/73/
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-7d8211603a3d04384812b481b0ae01205a287a72
cd investigate-gcc-7d8211603a3d04384812b481b0ae01205a287a72
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-bisect-gnu-master-arm-check_bootstrap/73… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/73… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/73… --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
cd gcc
# Reproduce first_bad build
git checkout --detach 7d8211603a3d04384812b481b0ae01205a287a72
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach b0ab968999c9af88d45acf552ca673ef3960306a
../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-bisect-gnu-master-arm-check_bootstrap/73…
Build log: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/73…
Full commit (up to 1000 lines):
<cut>
commit 7d8211603a3d04384812b481b0ae01205a287a72
Author: Richard Biener <rguenther(a)suse.de>
Date: Wed Jun 30 16:28:50 2021 +0200
tree-optimization/101178 - handle VEC_PERM in SLP permute propagation
This adds handling of VEC_PERM nodes to SLP permute propagation.
Previously VEC_PERM acted as forced materialization of incoming
permutes since it is a good place to do that (with the constraint
of those only appearing for two-operator nodes). The following
patch, in addition to supporting (but not forcing) this, enables
VEC_PERM nodes acting as "any" permute on the outgoing side since
they also can consume arbitrary permutes on that side.
This again (meh) changes how we represent permutes and materialization
on the graph vertices now explicitely having the common incoming
permute as well as an outgoing permute and in case both are
different the vertex acts as materialization point of the incoming
permute.
2021-06-30 Richard Biener <rguenther(a)suse.de>
PR tree-optimization/101178
* tree-vect-slp.c (slpg_vertex::materialize): Remove.
(slpg::perm_in): Add.
(slpg::get_perm_in): Remove.
(slpg::get_perm_materialized): Add.
(vect_optimize_slp): Handle VEC_PERM nodes more optimally
during permute propagation and materialization.
* gcc.dg/vect/bb-slp-72.c: New testcase.
* gcc.dg/vect/bb-slp-73.c: Likewise.
* gcc.dg/vect/bb-slp-74.c: Likewise.
---
gcc/testsuite/gcc.dg/vect/bb-slp-72.c | 29 +++++
gcc/testsuite/gcc.dg/vect/bb-slp-73.c | 29 +++++
gcc/testsuite/gcc.dg/vect/bb-slp-74.c | 30 +++++
gcc/tree-vect-slp.c | 200 ++++++++++++++++++++--------------
4 files changed, 204 insertions(+), 84 deletions(-)
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-72.c b/gcc/testsuite/gcc.dg/vect/bb-slp-72.c
new file mode 100644
index 00000000000..5b243fc1ace
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-72.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+double x[2], y[2], z[2], w[2];
+
+void __attribute__((noipa)) foo ()
+{
+ double tem0 = x[1] + y[1];
+ double tem1 = x[0] - y[0];
+ double tem2 = z[1] * tem0;
+ double tem3 = z[0] * tem1;
+ z[0] = tem2 - w[0];
+ z[1] = tem3 + w[1];
+}
+
+int main()
+{
+ check_vect ();
+
+ x[0] = 1.; x[1] = 2.;
+ y[0] = 7.; y[1] = -5.;
+ z[0] = 2.; z[1] = 3.;
+ w[0] = 9.; w[1] = -5.;
+ foo ();
+ if (z[0] != -18. || z[1] != -17.)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-73.c b/gcc/testsuite/gcc.dg/vect/bb-slp-73.c
new file mode 100644
index 00000000000..d4c8a514b1c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-73.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+double x[2], y[2], z[2], w[2];
+
+void __attribute__((noipa)) foo ()
+{
+ double tem0 = x[1] + y[1];
+ double tem1 = x[0] - y[0];
+ double tem2 = z[1] * tem0;
+ double tem3 = z[0] * tem1;
+ z[0] = tem2 - w[1];
+ z[1] = tem3 + w[0];
+}
+
+int main()
+{
+ check_vect ();
+
+ x[0] = 1.; x[1] = 2.;
+ y[0] = 7.; y[1] = -5.;
+ z[0] = 2.; z[1] = 3.;
+ w[0] = 9.; w[1] = -5.;
+ foo ();
+ if (z[0] != -4. || z[1] != -3.)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-74.c b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c
new file mode 100644
index 00000000000..d3d5a02a29b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-74.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+double a[2], b[2], c[2];
+
+void __attribute__((noipa)) foo ()
+{
+ double tem0 = a[1] + b[1];
+ double tem1 = a[0] - b[0];
+ c[0] = 2. * tem0;
+ c[1] = 5. * tem1;
+}
+
+int main()
+{
+ check_vect ();
+
+ a[0] = 1.; a[1] = 3.;
+ b[0] = -5.; b[1] = 13.;
+ foo ();
+ if (c[0] != 32. || c[1] != 30.)
+ __builtin_abort ();
+ return 0;
+}
+
+/* We'd like to see at most one VEC_PERM_EXPR, not one for a blend
+ and one for a permute materialized somewhere else. But addsub
+ pattern recog can likely get in the way here. */
+/* { dg-final { scan-tree-dump-times " \[^ \]\+ = VEC_PERM_EXPR" 1 "slp2" } } */
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 10195d3629f..966b281ffae 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -3470,16 +3470,19 @@ vect_analyze_slp (vec_info *vinfo, unsigned max_tree_size)
struct slpg_vertex
{
slpg_vertex (slp_tree node_)
- : node (node_), perm_out (-1), materialize (0) {}
+ : node (node_), perm_in (-1), perm_out (-1) {}
- int get_perm_in () const { return materialize ? materialize : perm_out; }
+ int get_perm_materialized () const
+ { return perm_in != perm_out ? perm_in : 0; }
slp_tree node;
- /* The permutation on the outgoing lanes (towards SLP parents). */
+ /* The common permutation on the incoming lanes (towards SLP children). */
+ int perm_in;
+ /* The permutation on the outgoing lanes (towards SLP parents). When
+ the node is a materialization point for a permute this differs
+ from perm_in (and is then usually zero). Materialization happens
+ on the input side. */
int perm_out;
- /* The permutation that is applied by this node. perm_out is
- relative to this. */
- int materialize;
};
/* Fill the vertices and leafs vector with all nodes in the SLP graph. */
@@ -3614,7 +3617,11 @@ vect_optimize_slp (vec_info *vinfo)
/* Leafs do not change across iterations. Note leafs also double
as entries to the reverse graph. */
if (!slpg->vertices[idx].succ)
- vertices[idx].perm_out = 0;
+ {
+ vertices[idx].perm_in = 0;
+ vertices[idx].perm_out = 0;
+ }
+
/* Loads are the only thing generating permutes. */
if (!SLP_TREE_LOAD_PERMUTATION (node).exists ())
continue;
@@ -3663,6 +3670,7 @@ vect_optimize_slp (vec_info *vinfo)
for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
perm[j] = SLP_TREE_LOAD_PERMUTATION (node)[j] - imin;
perms.safe_push (perm);
+ vertices[idx].perm_in = perms.length () - 1;
vertices[idx].perm_out = perms.length () - 1;
}
@@ -3702,8 +3710,11 @@ vect_optimize_slp (vec_info *vinfo)
if (STMT_VINFO_DATA_REF (rep)
&& DR_IS_WRITE (STMT_VINFO_DATA_REF (rep)))
{
+ /* ??? We're forcing materialization in place
+ of the child here, we'd need special handling
+ in materialization to leave perm_in -1 here. */
+ vertices[idx].perm_in = 0;
vertices[idx].perm_out = 0;
- continue;
}
/* We cannot move a permute across an operation that is
not independent on lanes. Note this is an explicit
@@ -3717,20 +3728,19 @@ vect_optimize_slp (vec_info *vinfo)
case CFN_COMPLEX_MUL:
case CFN_COMPLEX_MUL_CONJ:
case CFN_VEC_ADDSUB:
+ vertices[idx].perm_in = 0;
vertices[idx].perm_out = 0;
- continue;
default:;
}
}
- int perm;
if (!slpg->vertices[idx].succ)
/* Pick up pre-computed leaf values. */
- perm = vertices[idx].perm_out;
+ ;
else
{
bool any_succ_perm_out_m1 = false;
- perm = vertices[idx].get_perm_in ();
+ int perm_in = vertices[idx].perm_in;
for (graph_edge *succ = slpg->vertices[idx].succ;
succ; succ = succ->succ_next)
{
@@ -3752,18 +3762,18 @@ vect_optimize_slp (vec_info *vinfo)
any_succ_perm_out_m1 = true;
continue;
}
- if (perm == -1)
- perm = succ_perm;
+ if (perm_in == -1)
+ perm_in = succ_perm;
else if (succ_perm == 0
- || !vect_slp_perms_eq (perms, perm, succ_perm))
+ || !vect_slp_perms_eq (perms, perm_in, succ_perm))
{
- perm = 0;
+ perm_in = 0;
break;
}
}
/* Adjust any incoming permutes we treated optimistically. */
- if (perm != -1 && any_succ_perm_out_m1)
+ if (perm_in != -1 && any_succ_perm_out_m1)
{
for (graph_edge *succ = slpg->vertices[idx].succ;
succ; succ = succ->succ_next)
@@ -3772,24 +3782,36 @@ vect_optimize_slp (vec_info *vinfo)
if (vertices[succ->dest].perm_out == -1
&& SLP_TREE_DEF_TYPE (succ_node) != vect_external_def
&& SLP_TREE_DEF_TYPE (succ_node) != vect_constant_def)
- vertices[succ->dest].perm_out = perm;
+ {
+ vertices[succ->dest].perm_out = perm_in;
+ /* And ensure this propagates. */
+ if (vertices[succ->dest].perm_in == -1)
+ vertices[succ->dest].perm_in = perm_in;
+ }
}
changed = true;
}
- if (!vect_slp_perms_eq (perms, perm,
- vertices[idx].get_perm_in ()))
+ if (!vect_slp_perms_eq (perms, perm_in,
+ vertices[idx].perm_in))
{
/* Make sure we eventually converge. */
- gcc_checking_assert (vertices[idx].get_perm_in () == -1
- || perm == 0);
- if (perm == 0)
- {
- vertices[idx].perm_out = 0;
- vertices[idx].materialize = 0;
- }
- if (!vertices[idx].materialize)
- vertices[idx].perm_out = perm;
+ gcc_checking_assert (vertices[idx].perm_in == -1
+ || perm_in == 0);
+ vertices[idx].perm_in = perm_in;
+
+ /* While we can handle VEC_PERM nodes as transparent
+ pass-through they can be a cheap materialization
+ point as well. In addition they can act as source
+ of a random permutation as well.
+ The following ensures that former materialization
+ points that now have zero incoming permutes no
+ longer appear as such and that former "any" permutes
+ get pass-through. We keep VEC_PERM nodes optimistic
+ as "any" outgoing permute though. */
+ if (vertices[idx].perm_out != 0
+ && SLP_TREE_CODE (node) != VEC_PERM_EXPR)
+ vertices[idx].perm_out = perm_in;
changed = true;
}
}
@@ -3799,25 +3821,19 @@ vect_optimize_slp (vec_info *vinfo)
if (!do_materialization)
continue;
+ int perm = vertices[idx].perm_out;
if (perm == 0 || perm == -1)
continue;
/* Decide on permute materialization. Look whether there's
a use (pred) edge that is permuted differently than us.
- In that case mark ourselves so the permutation is applied.
- For VEC_PERM_EXPRs the permutation doesn't carry along
- from children to parents so force materialization at the
- point of the VEC_PERM_EXPR. In principle VEC_PERM_EXPRs
- are a source of an arbitrary permutation again, similar
- to constants/externals - that's something we do not yet
- optimally handle. */
- bool all_preds_permuted = (SLP_TREE_CODE (node) != VEC_PERM_EXPR
- && slpg->vertices[idx].pred != NULL);
+ In that case mark ourselves so the permutation is applied. */
+ bool all_preds_permuted = slpg->vertices[idx].pred != NULL;
if (all_preds_permuted)
for (graph_edge *pred = slpg->vertices[idx].pred;
pred; pred = pred->pred_next)
{
- int pred_perm = vertices[pred->src].get_perm_in ();
+ int pred_perm = vertices[pred->src].perm_in;
gcc_checking_assert (pred_perm != -1);
if (!vect_slp_perms_eq (perms, perm, pred_perm))
{
@@ -3827,10 +3843,8 @@ vect_optimize_slp (vec_info *vinfo)
}
if (!all_preds_permuted)
{
- if (!vertices[idx].materialize)
- changed = true;
- vertices[idx].materialize = perm;
vertices[idx].perm_out = 0;
+ changed = true;
}
}
@@ -3848,46 +3862,43 @@ vect_optimize_slp (vec_info *vinfo)
/* Materialize. */
for (i = 0; i < vertices.length (); ++i)
{
- int perm = vertices[i].get_perm_in ();
- if (perm <= 0)
- continue;
-
+ int perm_in = vertices[i].perm_in;
slp_tree node = vertices[i].node;
- /* First permute invariant/external original successors. */
+ /* First permute invariant/external original successors, we handle
+ those optimistically during propagation and duplicate them if
+ they are used with different permutations. */
unsigned j;
slp_tree child;
- FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
- {
- if (!child
- || (SLP_TREE_DEF_TYPE (child) != vect_constant_def
- && SLP_TREE_DEF_TYPE (child) != vect_external_def))
- continue;
+ if (perm_in > 0)
+ FOR_EACH_VEC_ELT (SLP_TREE_CHILDREN (node), j, child)
+ {
+ if (!child
+ || (SLP_TREE_DEF_TYPE (child) != vect_constant_def
+ && SLP_TREE_DEF_TYPE (child) != vect_external_def))
+ continue;
- /* If the vector is uniform there's nothing to do. */
- if (vect_slp_tree_uniform_p (child))
- continue;
+ /* If the vector is uniform there's nothing to do. */
+ if (vect_slp_tree_uniform_p (child))
+ continue;
- /* We can end up sharing some externals via two_operator
- handling. Be prepared to unshare those. */
- if (child->refcnt != 1)
- {
- gcc_assert (slpg->vertices[child->vertex].pred->pred_next);
- SLP_TREE_CHILDREN (node)[j] = child
- = vect_create_new_slp_node
- (SLP_TREE_SCALAR_OPS (child).copy ());
- }
- vect_slp_permute (perms[perm],
- SLP_TREE_SCALAR_OPS (child), true);
- }
+ /* We can end up sharing some externals via two_operator
+ handling. Be prepared to unshare those. */
+ if (child->refcnt != 1)
+ {
+ gcc_assert (slpg->vertices[child->vertex].pred->pred_next);
+ SLP_TREE_CHILDREN (node)[j] = child
+ = vect_create_new_slp_node
+ (SLP_TREE_SCALAR_OPS (child).copy ());
+ }
+ vect_slp_permute (perms[perm_in],
+ SLP_TREE_SCALAR_OPS (child), true);
+ }
- if (vertices[i].materialize)
+ if (SLP_TREE_CODE (node) == VEC_PERM_EXPR)
{
- if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
- /* For loads simply drop the permutation, the load permutation
- already performs the desired permutation. */
- ;
- else if (SLP_TREE_LANE_PERMUTATION (node).exists ())
+ /* Apply the common permutes to the input vectors. */
+ if (perm_in > 0)
{
/* If the node is already a permute node we can apply
the permutation to the lane selection, effectively
@@ -3896,12 +3907,30 @@ vect_optimize_slp (vec_info *vinfo)
dump_printf_loc (MSG_NOTE, vect_location,
"simplifying permute node %p\n",
node);
-
for (unsigned k = 0;
k < SLP_TREE_LANE_PERMUTATION (node).length (); ++k)
SLP_TREE_LANE_PERMUTATION (node)[k].second
- = perms[perm][SLP_TREE_LANE_PERMUTATION (node)[k].second];
+ = perms[perm_in][SLP_TREE_LANE_PERMUTATION (node)[k].second];
+ }
+ /* Apply the anticipated output permute to the permute and
+ stmt vectors. */
+ int perm_out = vertices[i].perm_out;
+ if (perm_out > 0)
+ {
+ vect_slp_permute (perms[perm_out],
+ SLP_TREE_SCALAR_STMTS (node), true);
+ vect_slp_permute (perms[perm_out],
+ SLP_TREE_LANE_PERMUTATION (node), true);
}
+ }
+ else if (vertices[i].get_perm_materialized () != 0)
+ {
+ if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
+ /* For loads simply drop the permutation, the load permutation
+ already performs the desired permutation. */
+ ;
+ else if (SLP_TREE_LANE_PERMUTATION (node).exists ())
+ gcc_unreachable ();
else
{
if (dump_enabled_p ())
@@ -3916,7 +3945,7 @@ vect_optimize_slp (vec_info *vinfo)
SLP_TREE_CHILDREN (node) = vNULL;
SLP_TREE_SCALAR_STMTS (copy)
= SLP_TREE_SCALAR_STMTS (node).copy ();
- vect_slp_permute (perms[perm],
+ vect_slp_permute (perms[perm_in],
SLP_TREE_SCALAR_STMTS (copy), true);
gcc_assert (!SLP_TREE_SCALAR_OPS (node).exists ());
SLP_TREE_REPRESENTATIVE (copy) = SLP_TREE_REPRESENTATIVE (node);
@@ -3936,28 +3965,31 @@ vect_optimize_slp (vec_info *vinfo)
SLP_TREE_LANE_PERMUTATION (node).create (SLP_TREE_LANES (node));
for (unsigned j = 0; j < SLP_TREE_LANES (node); ++j)
SLP_TREE_LANE_PERMUTATION (node)
- .quick_push (std::make_pair (0, perms[perm][j]));
+ .quick_push (std::make_pair (0, perms[perm_in][j]));
SLP_TREE_CODE (node) = VEC_PERM_EXPR;
}
}
- else
+ else if (perm_in > 0) /* perm_in == perm_out */
{
/* Apply the reverse permutation to our stmts. */
- vect_slp_permute (perms[perm],
+ vect_slp_permute (perms[perm_in],
SLP_TREE_SCALAR_STMTS (node), true);
- /* And to the load permutation, which we can simply
+ /* And to the lane/load permutation, which we can simply
make regular by design. */
if (SLP_TREE_LOAD_PERMUTATION (node).exists ())
{
+ gcc_assert (!SLP_TREE_LANE_PERMUTATION (node).exists ());
/* ??? When we handle non-bijective permutes the idea
is that we can force the load-permutation to be
{ min, min + 1, min + 2, ... max }. But then the
scalar defs might no longer match the lane content
which means wrong-code with live lane vectorization.
So we possibly have to have NULL entries for those. */
- vect_slp_permute (perms[perm],
+ vect_slp_permute (perms[perm_in],
SLP_TREE_LOAD_PERMUTATION (node), true);
}
+ else if (SLP_TREE_LANE_PERMUTATION (node).exists ())
+ gcc_unreachable ();
}
}
@@ -3991,14 +4023,14 @@ vect_optimize_slp (vec_info *vinfo)
}
else if (SLP_TREE_LOAD_PERMUTATION (old).exists ()
&& SLP_TREE_REF_COUNT (old) == 1
- && vertices[old->vertex].materialize)
+ && vertices[old->vertex].get_perm_materialized () != 0)
{
/* ??? For loads the situation is more complex since
we can't modify the permute in place in case the
node is used multiple times. In fact for loads this
should be somehow handled in the propagation engine. */
/* Apply the reverse permutation to our stmts. */
- int perm = vertices[old->vertex].get_perm_in ();
+ int perm = vertices[old->vertex].get_perm_materialized ();
vect_slp_permute (perms[perm],
SLP_TREE_SCALAR_STMTS (old), true);
vect_slp_permute (perms[perm],
</cut>
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_gnu_tk1/gnu-release-arm-spec2k6-O3_LTO. So far, this commit has regressed CI configurations:
- tcwg_bmk_gnu_tk1/gnu-release-arm-spec2k6-O3_LTO
Culprit:
<cut>
commit 9b0365879b3c4917f5a2485a1fca8bb678484bfe
Author: Richard Sandiford <richard.sandiford(a)arm.com>
Date: Mon Oct 7 08:39:12 2019 +0000
[IRA] Handle fully-tied destinations in a similar way to earlyclobbers
IRA's make_early_clobber_and_input_conflicts checks for cases in
which an output operand is likely to be an earlyclobber and an input
operand is unlikely to be tieable with it. If so, the allocno for
the output conflicts with the allocno for the input. This seems
to work well.
However, a similar situation arises if an output operand is likely
to be tied to one of a set of input operands X and if another input
operand has a different value from all of the operands in X.
E.g. if we have:
0: "=r, r"
1: "0, r"
2: "r, 0"
3: "r, r"
operand 0 will always be tied to operand 1 or operand 2, so if operand 3
is different from them both, operand 0 acts like an earlyclobber as far
as operand 3 (only) is concerned. The same is true for operand 2 in:
0: "=r"
1: "0"
2: "r"
In the second example, we'd normally have a copy between operand 1 and
operand 0 if operand 1 dies in the instruction, and so there's rarely
a problem. But if operand 1 doesn't die in the instruction, operand 0
still acts as an earlyclobber for operand 2 (if different from operand 1),
since in that case LRA must copy operand 1 to operand 0 before the
instruction.
As the existing comment says:
Avoid introducing unnecessary conflicts by checking classes of the
constraints and pseudos because otherwise significant code
degradation is possible for some targets.
I think that's doubly true here. E.g. it's perfectly reasonable to have
constraints like:
0: "=r, r"
1: "0, r"
2: "r, r"
on targets like s390 that have shorter instructions for tied operands,
but that don't want the size difference to influence RA too much.
We shouldn't treat operand 0 as earlyclobber wrt operand 2 in that case.
This patch therefore treats a normal tied non-earlyclobber output as
being effectively earlyclobber wrt to an input if it is so for *all*
preferred alternatives.
2019-10-07 Richard Sandiford <richard.sandiford(a)arm.com>
gcc/
* ira-lives.c (check_and_make_def_conflict): Handle cases in which
DEF is not a true earlyclobber but is tied to a specific input
operand, and so is effectively earlyclobber wrt inputs that have
different values.
(make_early_clobber_and_input_conflicts): Pass this case to the above.
From-SVN: r276650
</cut>
Results regressed to (for first_bad == 9b0365879b3c4917f5a2485a1fca8bb678484bfe)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O3_LTO_marm -- artifacts/build-9b0365879b3c4917f5a2485a1fca8bb678484bfe/results_id:
1
# 470.lbm,lbm_base.default regressed by 122
# 454.calculix,calculix_base.default regressed by 105
from (for last_good == ad00d6c1746fdcbfd86b2d50f2500d7ccb0d1691)
# reset_artifacts:
-10
# build_abe binutils:
-9
# build_abe stage1 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-8
# build_abe linux:
-7
# build_abe glibc:
-6
# build_abe stage2 -- --set gcc_override_configure=--with-mode=arm --set gcc_override_configure=--disable-libsanitizer:
-5
# true:
0
# benchmark -O3_LTO_marm -- artifacts/build-ad00d6c1746fdcbfd86b2d50f2500d7ccb0d1691/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Results ID of last_good: tk1_32/tcwg_bmk_gnu_tk1/bisect-gnu-release-arm-spec2k6-O3_LTO/1079
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Results ID of first_bad: tk1_32/tcwg_bmk_gnu_tk1/bisect-gnu-release-arm-spec2k6-O3_LTO/1049
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-9b0365879b3c4917f5a2485a1fca8bb678484bfe
cd investigate-gcc-9b0365879b3c4917f5a2485a1fca8bb678484bfe
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_gnu-bisect-tcwg_bmk_tk1-gnu-release-a… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a… --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
cd gcc
# Reproduce first_bad build
git checkout --detach 9b0365879b3c4917f5a2485a1fca8bb678484bfe
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach ad00d6c1746fdcbfd86b2d50f2500d7ccb0d1691
../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_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tk1-gnu-release-a…
Full commit (up to 1000 lines):
<cut>
commit 9b0365879b3c4917f5a2485a1fca8bb678484bfe
Author: Richard Sandiford <richard.sandiford(a)arm.com>
Date: Mon Oct 7 08:39:12 2019 +0000
[IRA] Handle fully-tied destinations in a similar way to earlyclobbers
IRA's make_early_clobber_and_input_conflicts checks for cases in
which an output operand is likely to be an earlyclobber and an input
operand is unlikely to be tieable with it. If so, the allocno for
the output conflicts with the allocno for the input. This seems
to work well.
However, a similar situation arises if an output operand is likely
to be tied to one of a set of input operands X and if another input
operand has a different value from all of the operands in X.
E.g. if we have:
0: "=r, r"
1: "0, r"
2: "r, 0"
3: "r, r"
operand 0 will always be tied to operand 1 or operand 2, so if operand 3
is different from them both, operand 0 acts like an earlyclobber as far
as operand 3 (only) is concerned. The same is true for operand 2 in:
0: "=r"
1: "0"
2: "r"
In the second example, we'd normally have a copy between operand 1 and
operand 0 if operand 1 dies in the instruction, and so there's rarely
a problem. But if operand 1 doesn't die in the instruction, operand 0
still acts as an earlyclobber for operand 2 (if different from operand 1),
since in that case LRA must copy operand 1 to operand 0 before the
instruction.
As the existing comment says:
Avoid introducing unnecessary conflicts by checking classes of the
constraints and pseudos because otherwise significant code
degradation is possible for some targets.
I think that's doubly true here. E.g. it's perfectly reasonable to have
constraints like:
0: "=r, r"
1: "0, r"
2: "r, r"
on targets like s390 that have shorter instructions for tied operands,
but that don't want the size difference to influence RA too much.
We shouldn't treat operand 0 as earlyclobber wrt operand 2 in that case.
This patch therefore treats a normal tied non-earlyclobber output as
being effectively earlyclobber wrt to an input if it is so for *all*
preferred alternatives.
2019-10-07 Richard Sandiford <richard.sandiford(a)arm.com>
gcc/
* ira-lives.c (check_and_make_def_conflict): Handle cases in which
DEF is not a true earlyclobber but is tied to a specific input
operand, and so is effectively earlyclobber wrt inputs that have
different values.
(make_early_clobber_and_input_conflicts): Pass this case to the above.
From-SVN: r276650
---
gcc/ChangeLog | 8 ++++++
gcc/ira-lives.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++----------
2 files changed, 80 insertions(+), 14 deletions(-)
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ce915859592..798d16cf0c6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2019-10-07 Richard Sandiford <richard.sandiford(a)arm.com>
+
+ * ira-lives.c (check_and_make_def_conflict): Handle cases in which
+ DEF is not a true earlyclobber but is tied to a specific input
+ operand, and so is effectively earlyclobber wrt inputs that have
+ different values.
+ (make_early_clobber_and_input_conflicts): Pass this case to the above.
+
2019-10-07 Richard Sandiford <richard.sandiford(a)arm.com>
* machmode.h (opt_mode): Mark constructors with CONSTEXPR.
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index cce73a1c3d4..098b0e73953 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -633,9 +633,28 @@ check_and_make_def_use_conflict (rtx dreg, rtx orig_dreg,
/* Check and make if necessary conflicts for definition DEF of class
DEF_CL of the current insn with input operands. Process only
- constraints of alternative ALT. */
+ constraints of alternative ALT.
+
+ One of three things is true when this function is called:
+
+ (1) DEF is an earlyclobber for alternative ALT. Input operands then
+ conflict with DEF in ALT unless they explicitly match DEF via 0-9
+ constraints.
+
+ (2) DEF matches (via 0-9 constraints) an operand that is an
+ earlyclobber for alternative ALT. Other input operands then
+ conflict with DEF in ALT.
+
+ (3) [FOR_TIE_P] Some input operand X matches DEF for alternative ALT.
+ Input operands with a different value from X then conflict with
+ DEF in ALT.
+
+ However, there's still a judgement call to make when deciding
+ whether a conflict in ALT is important enough to be reflected
+ in the pan-alternative allocno conflict set. */
static void
-check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
+check_and_make_def_conflict (int alt, int def, enum reg_class def_cl,
+ bool for_tie_p)
{
int use, use_match;
ira_allocno_t a;
@@ -669,14 +688,40 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
if (use == def || recog_data.operand_type[use] == OP_OUT)
continue;
+ /* An earlyclobber on DEF doesn't apply to an input operand X if X
+ explicitly matches DEF, but it applies to other input operands
+ even if they happen to be the same value as X.
+
+ In contrast, if an input operand X is tied to a non-earlyclobber
+ DEF, there's no conflict with other input operands that have the
+ same value as X. */
+ if (op_alt[use].matches == def
+ || (for_tie_p
+ && rtx_equal_p (recog_data.operand[use],
+ recog_data.operand[op_alt[def].matched])))
+ continue;
+
if (op_alt[use].anything_ok)
use_cl = ALL_REGS;
else
use_cl = op_alt[use].cl;
+ if (use_cl == NO_REGS)
+ continue;
+
+ /* If DEF is simply a tied operand, ignore cases in which this
+ alternative requires USE to have a likely-spilled class.
+ Adding a conflict would just constrain USE further if DEF
+ happens to be allocated first. */
+ if (for_tie_p && targetm.class_likely_spilled_p (use_cl))
+ continue;
/* If there's any alternative that allows USE to match DEF, do not
record a conflict. If that causes us to create an invalid
- instruction due to the earlyclobber, reload must fix it up. */
+ instruction due to the earlyclobber, reload must fix it up.
+
+ Likewise, if we're treating a tied DEF like a partial earlyclobber,
+ do not record a conflict if there's another alternative in which
+ DEF is neither tied nor earlyclobber. */
for (alt1 = 0; alt1 < recog_data.n_alternatives; alt1++)
{
if (!TEST_BIT (preferred_alternatives, alt1))
@@ -691,6 +736,12 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
&& recog_data.constraints[use - 1][0] == '%'
&& op_alt1[use - 1].matches == def))
break;
+ if (for_tie_p
+ && !op_alt1[def].earlyclobber
+ && op_alt1[def].matched < 0
+ && alternative_class (op_alt1, def) != NO_REGS
+ && alternative_class (op_alt1, use) != NO_REGS)
+ break;
}
if (alt1 < recog_data.n_alternatives)
@@ -701,8 +752,7 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
if ((use_match = op_alt[use].matches) >= 0)
{
- if (use_match == def)
- continue;
+ gcc_checking_assert (use_match != def);
if (op_alt[use_match].anything_ok)
use_cl = ALL_REGS;
@@ -717,7 +767,11 @@ check_and_make_def_conflict (int alt, int def, enum reg_class def_cl)
/* Make conflicts of early clobber pseudo registers of the current
insn with its inputs. Avoid introducing unnecessary conflicts by
checking classes of the constraints and pseudos because otherwise
- significant code degradation is possible for some targets. */
+ significant code degradation is possible for some targets.
+
+ For these purposes, tying an input to an output makes that output act
+ like an earlyclobber for inputs with a different value, since the output
+ register then has a predetermined purpose on input to the instruction. */
static void
make_early_clobber_and_input_conflicts (void)
{
@@ -732,15 +786,19 @@ make_early_clobber_and_input_conflicts (void)
if (TEST_BIT (preferred_alternatives, alt))
for (def = 0; def < n_operands; def++)
{
- def_cl = NO_REGS;
- if (op_alt[def].earlyclobber)
+ if (op_alt[def].anything_ok)
+ def_cl = ALL_REGS;
+ else
+ def_cl = op_alt[def].cl;
+ if (def_cl != NO_REGS)
{
- if (op_alt[def].anything_ok)
- def_cl = ALL_REGS;
- else
- def_cl = op_alt[def].cl;
- check_and_make_def_conflict (alt, def, def_cl);
+ if (op_alt[def].earlyclobber)
+ check_and_make_def_conflict (alt, def, def_cl, false);
+ else if (op_alt[def].matched >= 0
+ && !targetm.class_likely_spilled_p (def_cl))
+ check_and_make_def_conflict (alt, def, def_cl, true);
}
+
if ((def_match = op_alt[def].matches) >= 0
&& (op_alt[def_match].earlyclobber
|| op_alt[def].earlyclobber))
@@ -749,7 +807,7 @@ make_early_clobber_and_input_conflicts (void)
def_cl = ALL_REGS;
else
def_cl = op_alt[def_match].cl;
- check_and_make_def_conflict (alt, def, def_cl);
+ check_and_make_def_conflict (alt, def, def_cl, false);
}
}
}
</cut>
Successfully identified regression in *gcc* in CI configuration tcwg_gnu/gnu-master-arm-check_bootstrap. So far, this commit has regressed CI configurations:
- tcwg_gnu/gnu-master-arm-check_bootstrap
Culprit:
<cut>
commit 8a8a7d332d5d01db5aea7336a36d9fd71a679fb1
Author: Ian Lance Taylor <iant(a)golang.org>
Date: Mon Jun 28 16:47:55 2021 -0700
compiler: in composite literals use temps only for interfaces
For a composite literal we only need to introduce a temporary variable
if we may be converting to an interface type, so only do it then.
This saves over 80% of compilation time when using gccgo to compile
cmd/internal/obj/x86, as the GCC middle-end spends a lot of time
pointlessly computing interactions between temporary variables.
For PR debug/101064
For golang/go#46600
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/331513
</cut>
Results regressed to (for first_bad == 8a8a7d332d5d01db5aea7336a36d9fd71a679fb1)
# reset_artifacts:
-10
# build_abe bootstrap:
0
# build_abe check_bootstrap:
1
# # Comparing directories
# # REFERENCE: base-artifacts/sumfiles
# # CURRENT: /home/tcwg-buildslave/workspace/tcwg_gnu_2/artifacts/build-8a8a7d332d5d01db5aea7336a36d9fd71a679fb1/sumfiles
#
# # Comparing 12 common sum files:
# g++.sum
# gcc.sum
# gfortran.sum
# go.sum
# gotools.sum
# libatomic.sum
# libffi.sum
# libgo.sum
# libgomp.sum
# libitm.sum
# libstdc++.sum
# objc.sum
# Comparing:
# REFERENCE:/tmp/gxx-sum1.1601595
# CURRENT: /tmp/gxx-sum2.1601595
#
# ` +---------+---------+
# o RUN STATUS: | REF | RES |
# +------------------------------------------+---------+---------+
# | Passes [PASS] | 460522 | 460519 |
# | Unexpected fails [FAIL] | 194 | 197 |
# | Errors [ERROR] | 0 | 0 |
# | Unexpected passes [XPASS] | 15 | 15 |
# | Expected fails [XFAIL] | 2737 | 2737 |
# | Unresolved [UNRESOLVED] | 104 | 104 |
# | Unsupported [UNSUPPORTED] | 22896 | 22896 |
# | Untested [UNTESTED] | 10 | 10 |
# +------------------------------------------+---------+---------+
#
# REF PASS ratio: 0.952271
# RES PASS ratio: 0.952265
#
# o REGRESSIONS:
# +------------------------------------------+---------+
# | PASS now FAIL [PASS => FAIL] | 3 |
# +------------------------------------------+---------+
# | TOTAL_REGRESSIONS | 3 |
# +------------------------------------------+---------+
#
# - PASS now FAIL [PASS => FAIL]:
#
# Executed from: go.test/go-test.exp
# go:go.test/test/fixedbugs/issue19182.go execution, -O2 -g
# Executed from: /home/tcwg-buildslave/workspace/tcwg_gnu_2/abe/snapshots/gcc.git~master/libgo/libgo.exp
# libgo:os/signal
# libgo:sync/atomic
#
#
#
# o IMPROVEMENTS TO BE CHECKED:
# +------------------------------------------+---------+
# +------------------------------------------+---------+
# | TOTAL_IMPROVEMENTS_TO_BE_CHECKED | 0 |
# +------------------------------------------+---------+
#
#
# # Regressions found
# # Regressions in 12 common sum files found
from (for last_good == c60d9160b4d966dbea5b1bbea4f817c64d0bee2d)
# reset_artifacts:
-10
# build_abe bootstrap:
0
# build_abe check_bootstrap:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/72…
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/72…
Build top page/logs: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/72/
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-8a8a7d332d5d01db5aea7336a36d9fd71a679fb1
cd investigate-gcc-8a8a7d332d5d01db5aea7336a36d9fd71a679fb1
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-bisect-gnu-master-arm-check_bootstrap/72… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/72… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/72… --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
cd gcc
# Reproduce first_bad build
git checkout --detach 8a8a7d332d5d01db5aea7336a36d9fd71a679fb1
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach c60d9160b4d966dbea5b1bbea4f817c64d0bee2d
../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-bisect-gnu-master-arm-check_bootstrap/72…
Build log: https://ci.linaro.org/job/tcwg_gcc-bisect-gnu-master-arm-check_bootstrap/72…
Full commit (up to 1000 lines):
<cut>
commit 8a8a7d332d5d01db5aea7336a36d9fd71a679fb1
Author: Ian Lance Taylor <iant(a)golang.org>
Date: Mon Jun 28 16:47:55 2021 -0700
compiler: in composite literals use temps only for interfaces
For a composite literal we only need to introduce a temporary variable
if we may be converting to an interface type, so only do it then.
This saves over 80% of compilation time when using gccgo to compile
cmd/internal/obj/x86, as the GCC middle-end spends a lot of time
pointlessly computing interactions between temporary variables.
For PR debug/101064
For golang/go#46600
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/331513
---
gcc/go/gofrontend/MERGE | 2 +-
gcc/go/gofrontend/expressions.cc | 17 +++++++++++++----
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index f16fb9facc3..f7bcc8c484a 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-bcafcb3c39530bb325514d6377747eb3127d1a03
+cad187fe3aceb2a7d964b64c70dfa8c8ad24ce65
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 5d45e4baab4..94342b2f9b8 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -15148,7 +15148,7 @@ Struct_construction_expression::do_copy()
}
// Flatten a struct construction expression. Store the values into
-// temporaries in case they need interface conversion.
+// temporaries if they may need interface conversion.
Expression*
Struct_construction_expression::do_flatten(Gogo*, Named_object*,
@@ -15162,10 +15162,13 @@ Struct_construction_expression::do_flatten(Gogo*, Named_object*,
return this;
Location loc = this->location();
+ const Struct_field_list* fields = this->type_->struct_type()->fields();
+ Struct_field_list::const_iterator pf = fields->begin();
for (Expression_list::iterator pv = this->vals()->begin();
pv != this->vals()->end();
- ++pv)
+ ++pv, ++pf)
{
+ go_assert(pf != fields->end());
if (*pv != NULL)
{
if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type())
@@ -15173,7 +15176,8 @@ Struct_construction_expression::do_flatten(Gogo*, Named_object*,
go_assert(saw_errors());
return Expression::make_error(loc);
}
- if (!(*pv)->is_multi_eval_safe())
+ if (pf->type()->interface_type() != NULL
+ && !(*pv)->is_multi_eval_safe())
{
Temporary_statement* temp =
Statement::make_temporary(NULL, *pv, loc);
@@ -15448,7 +15452,7 @@ Array_construction_expression::do_check_types(Gogo*)
}
// Flatten an array construction expression. Store the values into
-// temporaries in case they need interface conversion.
+// temporaries if they may need interface conversion.
Expression*
Array_construction_expression::do_flatten(Gogo*, Named_object*,
@@ -15467,6 +15471,11 @@ Array_construction_expression::do_flatten(Gogo*, Named_object*,
if (this->is_constant_array() || this->is_static_initializer())
return this;
+ // If the array element type is not an interface type, we don't need
+ // temporaries.
+ if (this->type_->array_type()->element_type()->interface_type() == NULL)
+ return this;
+
Location loc = this->location();
for (Expression_list::iterator pv = this->vals()->begin();
pv != this->vals()->end();
</cut>
Successfully identified regression in *llvm* in CI configuration tcwg_bmk_llvm_tx1/llvm-master-aarch64-spec2k6-O2_LTO. So far, this commit has regressed CI configurations:
- tcwg_bmk_llvm_tx1/llvm-master-aarch64-spec2k6-O2_LTO
Culprit:
<cut>
commit 6998f8ae2d14e096aff33968f226587b5c1a193a
Author: David Sherwood <david.sherwood(a)arm.com>
Date: Wed Mar 10 08:34:19 2021 +0000
[LoopVectorize] Simplify scalar cost calculation in getInstructionCost
This patch simplifies the calculation of certain costs in
getInstructionCost when isScalarAfterVectorization() returns a true value.
There are a few places where we multiply a cost by a number N, i.e.
unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
return N * TTI.getArithmeticInstrCost(...
After some investigation it seems that there are only these cases that occur
in practice:
1. VF is a scalar, in which case N = 1.
2. VF is a vector. We can only get here if: a) the instruction is a
GEP/bitcast/PHI with scalar uses, or b) this is an update to an induction
variable that remains scalar.
I have changed the code so that N is assumed to always be 1. For GEPs
the cost is always 0, since this is calculated later on as part of the
load/store cost. PHI nodes are costed separately and were never previously
multiplied by VF. For all other cases I have added an assert that none of
the users needs scalarising, which didn't fire in any unit tests.
Only one test required fixing and I believe the original cost for the scalar
add instruction to have been wrong, since only one copy remains after
vectorisation.
I have also added a new test for the case when a pointer PHI feeds directly
into a store that will be scalarised as we were previously never testing it.
Differential Revision: https://reviews.llvm.org/D99718
</cut>
Results regressed to (for first_bad == 6998f8ae2d14e096aff33968f226587b5c1a193a)
# 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 -O2_LTO -- artifacts/build-6998f8ae2d14e096aff33968f226587b5c1a193a/results_id:
1
# 462.libquantum,libquantum_base.default regressed by 113
from (for last_good == c835630c25a4f9925517949579f66a43b113fbc9)
# 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 -O2_LTO -- artifacts/build-c835630c25a4f9925517949579f66a43b113fbc9/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-O2_LTO/1050
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-O2_LTO/1048
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-6998f8ae2d14e096aff33968f226587b5c1a193a
cd investigate-llvm-6998f8ae2d14e096aff33968f226587b5c1a193a
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
cd llvm
# Reproduce first_bad build
git checkout --detach 6998f8ae2d14e096aff33968f226587b5c1a193a
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach c835630c25a4f9925517949579f66a43b113fbc9
../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 6998f8ae2d14e096aff33968f226587b5c1a193a
Author: David Sherwood <david.sherwood(a)arm.com>
Date: Wed Mar 10 08:34:19 2021 +0000
[LoopVectorize] Simplify scalar cost calculation in getInstructionCost
This patch simplifies the calculation of certain costs in
getInstructionCost when isScalarAfterVectorization() returns a true value.
There are a few places where we multiply a cost by a number N, i.e.
unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
return N * TTI.getArithmeticInstrCost(...
After some investigation it seems that there are only these cases that occur
in practice:
1. VF is a scalar, in which case N = 1.
2. VF is a vector. We can only get here if: a) the instruction is a
GEP/bitcast/PHI with scalar uses, or b) this is an update to an induction
variable that remains scalar.
I have changed the code so that N is assumed to always be 1. For GEPs
the cost is always 0, since this is calculated later on as part of the
load/store cost. PHI nodes are costed separately and were never previously
multiplied by VF. For all other cases I have added an assert that none of
the users needs scalarising, which didn't fire in any unit tests.
Only one test required fixing and I believe the original cost for the scalar
add instruction to have been wrong, since only one copy remains after
vectorisation.
I have also added a new test for the case when a pointer PHI feeds directly
into a store that will be scalarised as we were previously never testing it.
Differential Revision: https://reviews.llvm.org/D99718
---
llvm/lib/Transforms/Vectorize/LoopVectorize.cpp | 73 +++++++++++++---------
.../AArch64/no_vector_instructions.ll | 2 +-
.../LoopVectorize/AArch64/predication_costs.ll | 35 +++++++++++
.../Transforms/LoopVectorize/scalarized-bitcast.ll | 40 ++++++++++++
4 files changed, 121 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
index 2b413fc49505..f25af23c86c2 100644
--- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
+++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -7383,10 +7383,39 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
Type *RetTy = I->getType();
if (canTruncateToMinimalBitwidth(I, VF))
RetTy = IntegerType::get(RetTy->getContext(), MinBWs[I]);
- VectorTy = isScalarAfterVectorization(I, VF) ? RetTy : ToVectorTy(RetTy, VF);
auto SE = PSE.getSE();
TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
+ auto hasSingleCopyAfterVectorization = [this](Instruction *I,
+ ElementCount VF) -> bool {
+ if (VF.isScalar())
+ return true;
+
+ auto Scalarized = InstsToScalarize.find(VF);
+ assert(Scalarized != InstsToScalarize.end() &&
+ "VF not yet analyzed for scalarization profitability");
+ return !Scalarized->second.count(I) &&
+ llvm::all_of(I->users(), [&](User *U) {
+ auto *UI = cast<Instruction>(U);
+ return !Scalarized->second.count(UI);
+ });
+ };
+
+ if (isScalarAfterVectorization(I, VF)) {
+ // With the exception of GEPs and PHIs, after scalarization there should
+ // only be one copy of the instruction generated in the loop. This is
+ // because the VF is either 1, or any instructions that need scalarizing
+ // have already been dealt with by the the time we get here. As a result,
+ // it means we don't have to multiply the instruction cost by VF.
+ assert(I->getOpcode() == Instruction::GetElementPtr ||
+ I->getOpcode() == Instruction::PHI ||
+ (I->getOpcode() == Instruction::BitCast &&
+ I->getType()->isPointerTy()) ||
+ hasSingleCopyAfterVectorization(I, VF));
+ VectorTy = RetTy;
+ } else
+ VectorTy = ToVectorTy(RetTy, VF);
+
// TODO: We need to estimate the cost of intrinsic calls.
switch (I->getOpcode()) {
case Instruction::GetElementPtr:
@@ -7514,21 +7543,16 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
Op2VK = TargetTransformInfo::OK_UniformValue;
SmallVector<const Value *, 4> Operands(I->operand_values());
- unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
- return N * TTI.getArithmeticInstrCost(
- I->getOpcode(), VectorTy, CostKind,
- TargetTransformInfo::OK_AnyValue,
- Op2VK, TargetTransformInfo::OP_None, Op2VP, Operands, I);
+ return TTI.getArithmeticInstrCost(
+ I->getOpcode(), VectorTy, CostKind, TargetTransformInfo::OK_AnyValue,
+ Op2VK, TargetTransformInfo::OP_None, Op2VP, Operands, I);
}
case Instruction::FNeg: {
assert(!VF.isScalable() && "VF is assumed to be non scalable.");
- unsigned N = isScalarAfterVectorization(I, VF) ? VF.getKnownMinValue() : 1;
- return N * TTI.getArithmeticInstrCost(
- I->getOpcode(), VectorTy, CostKind,
- TargetTransformInfo::OK_AnyValue,
- TargetTransformInfo::OK_AnyValue,
- TargetTransformInfo::OP_None, TargetTransformInfo::OP_None,
- I->getOperand(0), I);
+ return TTI.getArithmeticInstrCost(
+ I->getOpcode(), VectorTy, CostKind, TargetTransformInfo::OK_AnyValue,
+ TargetTransformInfo::OK_AnyValue, TargetTransformInfo::OP_None,
+ TargetTransformInfo::OP_None, I->getOperand(0), I);
}
case Instruction::Select: {
SelectInst *SI = cast<SelectInst>(I);
@@ -7583,6 +7607,10 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
VectorTy = ToVectorTy(getMemInstValueType(I), Width);
return getMemoryInstructionCost(I, VF);
}
+ case Instruction::BitCast:
+ if (I->getType()->isPointerTy())
+ return 0;
+ LLVM_FALLTHROUGH;
case Instruction::ZExt:
case Instruction::SExt:
case Instruction::FPToUI:
@@ -7593,8 +7621,7 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
case Instruction::SIToFP:
case Instruction::UIToFP:
case Instruction::Trunc:
- case Instruction::FPTrunc:
- case Instruction::BitCast: {
+ case Instruction::FPTrunc: {
// Computes the CastContextHint from a Load/Store instruction.
auto ComputeCCH = [&](Instruction *I) -> TTI::CastContextHint {
assert((isa<LoadInst>(I) || isa<StoreInst>(I)) &&
@@ -7672,14 +7699,7 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
}
}
- unsigned N;
- if (isScalarAfterVectorization(I, VF)) {
- assert(!VF.isScalable() && "VF is assumed to be non scalable");
- N = VF.getKnownMinValue();
- } else
- N = 1;
- return N *
- TTI.getCastInstrCost(Opcode, VectorTy, SrcVecTy, CCH, CostKind, I);
+ return TTI.getCastInstrCost(Opcode, VectorTy, SrcVecTy, CCH, CostKind, I);
}
case Instruction::Call: {
bool NeedToScalarize;
@@ -7694,11 +7714,8 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
case Instruction::ExtractValue:
return TTI.getInstructionCost(I, TTI::TCK_RecipThroughput);
default:
- // The cost of executing VF copies of the scalar instruction. This opcode
- // is unknown. Assume that it is the same as 'mul'.
- return VF.getKnownMinValue() * TTI.getArithmeticInstrCost(
- Instruction::Mul, VectorTy, CostKind) +
- getScalarizationOverhead(I, VF);
+ // This opcode is unknown. Assume that it is the same as 'mul'.
+ return TTI.getArithmeticInstrCost(Instruction::Mul, VectorTy, CostKind);
} // end of switch.
}
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/no_vector_instructions.ll b/llvm/test/Transforms/LoopVectorize/AArch64/no_vector_instructions.ll
index 247ea35ff5d0..3061998518ad 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/no_vector_instructions.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/no_vector_instructions.ll
@@ -6,7 +6,7 @@ target triple = "aarch64--linux-gnu"
; CHECK-LABEL: all_scalar
; CHECK: LV: Found scalar instruction: %i.next = add nuw nsw i64 %i, 2
-; CHECK: LV: Found an estimated cost of 2 for VF 2 For instruction: %i.next = add nuw nsw i64 %i, 2
+; CHECK: LV: Found an estimated cost of 1 for VF 2 For instruction: %i.next = add nuw nsw i64 %i, 2
; CHECK: LV: Not considering vector loop of width 2 because it will not generate any vector instructions
;
define void @all_scalar(i64* %a, i64 %n) {
diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/predication_costs.ll b/llvm/test/Transforms/LoopVectorize/AArch64/predication_costs.ll
index b0ebb4edf2ad..858b28ddd321 100644
--- a/llvm/test/Transforms/LoopVectorize/AArch64/predication_costs.ll
+++ b/llvm/test/Transforms/LoopVectorize/AArch64/predication_costs.ll
@@ -86,6 +86,41 @@ for.end:
ret void
}
+; CHECK-LABEL: predicated_store_phi
+;
+; Same as predicate_store except we use a pointer PHI to maintain the address
+;
+; CHECK: Found new scalar instruction: %addr = phi i32* [ %a, %entry ], [ %addr.next, %for.inc ]
+; CHECK: Found new scalar instruction: %addr.next = getelementptr inbounds i32, i32* %addr, i64 1
+; CHECK: Scalarizing and predicating: store i32 %tmp2, i32* %addr, align 4
+; CHECK: Found an estimated cost of 0 for VF 2 For instruction: %addr = phi i32* [ %a, %entry ], [ %addr.next, %for.inc ]
+; CHECK: Found an estimated cost of 3 for VF 2 For instruction: store i32 %tmp2, i32* %addr, align 4
+;
+define void @predicated_store_phi(i32* %a, i1 %c, i32 %x, i64 %n) {
+entry:
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ 0, %entry ], [ %i.next, %for.inc ]
+ %addr = phi i32 * [ %a, %entry ], [ %addr.next, %for.inc ]
+ %tmp1 = load i32, i32* %addr, align 4
+ %tmp2 = add nsw i32 %tmp1, %x
+ br i1 %c, label %if.then, label %for.inc
+
+if.then:
+ store i32 %tmp2, i32* %addr, align 4
+ br label %for.inc
+
+for.inc:
+ %i.next = add nuw nsw i64 %i, 1
+ %cond = icmp slt i64 %i.next, %n
+ %addr.next = getelementptr inbounds i32, i32* %addr, i64 1
+ br i1 %cond, label %for.body, label %for.end
+
+for.end:
+ ret void
+}
+
; CHECK-LABEL: predicated_udiv_scalarized_operand
;
; This test checks that we correctly compute the cost of the predicated udiv
diff --git a/llvm/test/Transforms/LoopVectorize/scalarized-bitcast.ll b/llvm/test/Transforms/LoopVectorize/scalarized-bitcast.ll
new file mode 100644
index 000000000000..0c97e6ac475e
--- /dev/null
+++ b/llvm/test/Transforms/LoopVectorize/scalarized-bitcast.ll
@@ -0,0 +1,40 @@
+; REQUIRES: asserts
+; RUN: opt -loop-vectorize -force-vector-width=2 -debug-only=loop-vectorize -S -o - < %s 2>&1 | FileCheck %s
+
+%struct.foo = type { i32, i64 }
+
+; CHECK: LV: Found an estimated cost of 0 for VF 2 For instruction: %0 = bitcast i64* %b to i32*
+
+; The bitcast below will be scalarized due to the predication in the loop. Bitcasts
+; between pointer types should be treated as free, despite the scalarization.
+define void @foo(%struct.foo* noalias nocapture %in, i32* noalias nocapture readnone %out, i64 %n) {
+entry:
+ br label %for.body
+
+for.body: ; preds = %entry, %if.end
+ %i.012 = phi i64 [ %inc, %if.end ], [ 0, %entry ]
+ %b = getelementptr inbounds %struct.foo, %struct.foo* %in, i64 %i.012, i32 1
+ %0 = bitcast i64* %b to i32*
+ %a = getelementptr inbounds %struct.foo, %struct.foo* %in, i64 %i.012, i32 0
+ %1 = load i32, i32* %a, align 8
+ %tobool.not = icmp eq i32 %1, 0
+ br i1 %tobool.not, label %if.end, label %land.lhs.true
+
+land.lhs.true: ; preds = %for.body
+ %2 = load i32, i32* %0, align 4
+ %cmp2 = icmp sgt i32 %2, 0
+ br i1 %cmp2, label %if.then, label %if.end
+
+if.then: ; preds = %land.lhs.true
+ %sub = add nsw i32 %2, -1
+ store i32 %sub, i32* %0, align 4
+ br label %if.end
+
+if.end: ; preds = %if.then, %land.lhs.true, %for.body
+ %inc = add nuw nsw i64 %i.012, 1
+ %exitcond.not = icmp eq i64 %inc, %n
+ br i1 %exitcond.not, label %for.end, label %for.body
+
+for.end: ; preds = %if.end
+ ret void
+}
</cut>
Successfully identified regression in *glibc* in CI configuration tcwg_bmk_gnu_tx1/gnu-master-aarch64-spec2k6-O2_LTO. So far, this commit has regressed CI configurations:
- tcwg_bmk_gnu_tx1/gnu-master-aarch64-spec2k6-O2_LTO
Culprit:
<cut>
commit 8208be389bce84be0e1c35a3daa0c3467418f921
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Mon Jun 28 08:33:57 2021 +0200
Install shared objects under their ABI names
Previously, the installed objects were named like libc-2.33.so,
and the ABI soname libc.so.6 was just a symbolic link.
The Makefile targets to install these symbolic links are no longer
needed after this, so they are removed with this commit. The more
general $(make-link) command (which invokes scripts/rellns-sh) is
retained because other symbolic links are still needed.
Reviewed-by: Carlos O'Donell <carlos(a)redhat.com>
Tested-by: Carlos O'Donell <carlos(a)rehdat.com>
</cut>
Results regressed to (for first_bad == 8208be389bce84be0e1c35a3daa0c3467418f921)
# 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
# true:
0
# benchmark -O2_LTO -- artifacts/build-8208be389bce84be0e1c35a3daa0c3467418f921/results_id:
1
# 434.zeusmp,zeusmp_base.default regressed by 7549591
# 435.gromacs,gromacs_base.default regressed by 10863956
# 447.dealII,dealII_base.default regressed by 12999253
# 454.calculix,calculix_base.default regressed by 3929138
# 465.tonto,tonto_base.default regressed by 12056000
# 459.GemsFDTD,GemsFDTD_base.default regressed by 7978538
# 410.bwaves,bwaves_base.default regressed by 8373106
# 416.gamess,gamess_base.default regressed by 4372732
# 481.wrf,wrf_base.default regressed by 8973237
# 436.cactusADM,cactusADM_base.default regressed by 4181826
# 437.leslie3d,leslie3d_base.default regressed by 7255644
from (for last_good == 6bf789d69e6be48419094ca98f064e00297a27d5)
# 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
# true:
0
# benchmark -O2_LTO -- artifacts/build-6bf789d69e6be48419094ca98f064e00297a27d5/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Results ID of last_good: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-master-aarch64-spec2k6-O2_LTO/976
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Results ID of first_bad: tx1_64/tcwg_bmk_gnu_tx1/bisect-gnu-master-aarch64-spec2k6-O2_LTO/988
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-glibc-8208be389bce84be0e1c35a3daa0c3467418f921
cd investigate-glibc-8208be389bce84be0e1c35a3daa0c3467418f921
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_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa… --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
cd glibc
# Reproduce first_bad build
git checkout --detach 8208be389bce84be0e1c35a3daa0c3467418f921
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach 6bf789d69e6be48419094ca98f064e00297a27d5
../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_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_gnu-bisect-tcwg_bmk_tx1-gnu-master-aa…
Full commit (up to 1000 lines):
<cut>
commit 8208be389bce84be0e1c35a3daa0c3467418f921
Author: Florian Weimer <fweimer(a)redhat.com>
Date: Mon Jun 28 08:33:57 2021 +0200
Install shared objects under their ABI names
Previously, the installed objects were named like libc-2.33.so,
and the ABI soname libc.so.6 was just a symbolic link.
The Makefile targets to install these symbolic links are no longer
needed after this, so they are removed with this commit. The more
general $(make-link) command (which invokes scripts/rellns-sh) is
retained because other symbolic links are still needed.
Reviewed-by: Carlos O'Donell <carlos(a)redhat.com>
Tested-by: Carlos O'Donell <carlos(a)rehdat.com>
---
Makefile | 6 ------
Makerules | 45 +++++----------------------------------------
NEWS | 8 ++++++++
elf/Makefile | 10 ++--------
4 files changed, 15 insertions(+), 54 deletions(-)
diff --git a/Makefile b/Makefile
index 0157b53cb8..f98d5a9e67 100644
--- a/Makefile
+++ b/Makefile
@@ -109,12 +109,6 @@ elf/ldso_install:
# Ignore the error if we cannot update /etc/ld.so.cache.
ifeq (no,$(cross-compiling))
ifeq (yes,$(build-shared))
-install: install-symbolic-link
-.PHONY: install-symbolic-link
-install-symbolic-link: subdir_install
- $(symbolic-link-prog) $(symbolic-link-list)
- rm -f $(symbolic-link-list)
-
install:
-test ! -x $(elf-objpfx)ldconfig || LC_ALL=C \
$(elf-objpfx)ldconfig $(addprefix -r ,$(install_root)) \
diff --git a/Makerules b/Makerules
index f2587907fb..596fa68376 100644
--- a/Makerules
+++ b/Makerules
@@ -990,14 +990,12 @@ versioned := $(strip $(foreach so,$(install-lib.so),\
install-lib.so-versioned := $(filter $(versioned), $(install-lib.so))
install-lib.so-unversioned := $(filter-out $(versioned), $(install-lib.so))
-# For libraries whose soname have version numbers, we install three files:
+# For libraries whose soname have version numbers, we install two files:
# $(inst_libdir)/libfoo.so -- for linking, symlink or ld script
-# $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME, symlink
-# $(inst_slibdir)/libfoo-X.Y.Z.so -- the real shared object file
+# $(inst_slibdir)/libfoo.so.NN -- for loading by SONAME
install-lib-nosubdir: $(install-lib.so-unversioned:%=$(inst_slibdir)/%) \
$(foreach L,$(install-lib.so-versioned),\
$(inst_libdir)/$L \
- $(inst_slibdir)/$(L:.so=)-$(version).so \
$(inst_slibdir)/$L$($L-version))
# Install all the unversioned shared libraries.
@@ -1030,35 +1028,10 @@ ln -f $(objpfx)/$(@F) $@
endef
endif
-ifeq (yes,$(build-shared))
-ifeq (no,$(cross-compiling))
-symbolic-link-prog := $(elf-objpfx)sln
-symbolic-link-list := $(elf-objpfx)symlink.list
-define make-shlib-link
-echo `$(..)scripts/rellns-sh -p $< $@` $@ >> $(symbolic-link-list)
-endef
-else # cross-compiling
-# We need a definition that can be used by elf/Makefile's install rules.
-symbolic-link-prog = $(LN_S)
-endif
-endif
-ifndef make-shlib-link
-define make-shlib-link
-rm -f $@
-$(LN_S) `$(..)scripts/rellns-sh -p $< $@` $@
-endef
-endif
-
ifdef libc.so-version
-# For a library specified to be version N, install three files:
-# libc.so -> libc.so.N (e.g. libc.so.6)
-# libc.so.6 -> libc-VERSION.so (e.g. libc-1.10.so)
-
-$(inst_slibdir)/libc.so$(libc.so-version): $(inst_slibdir)/libc-$(version).so \
- $(+force)
- $(make-shlib-link)
-$(inst_slibdir)/libc-$(version).so: $(common-objpfx)libc.so $(+force)
+$(inst_slibdir)/libc.so$(libc.so-version): $(common-objpfx)libc.so $(+force)
$(do-install-program)
+
install: $(inst_slibdir)/libc.so$(libc.so-version)
# This fragment of linker script gives the OUTPUT_FORMAT statement
@@ -1126,15 +1099,7 @@ include $(o-iterator)
generated += $(foreach o,$(versioned),$o$($o-version))
define o-iterator-doit
-$(inst_slibdir)/$o$($o-version): $(inst_slibdir)/$(o:.so=)-$(version).so \
- $(+force);
- $$(make-shlib-link)
-endef
-object-suffixes-left := $(versioned)
-include $(o-iterator)
-
-define o-iterator-doit
-$(inst_slibdir)/$(o:.so=)-$(version).so: $(objpfx)$o $(+force);
+$(inst_slibdir)/$o$($o-version): $(objpfx)$o $(+force);
$$(do-install-program)
endef
object-suffixes-left := $(versioned)
diff --git a/NEWS b/NEWS
index b24ebf9898..37ba4334c6 100644
--- a/NEWS
+++ b/NEWS
@@ -74,6 +74,14 @@ Deprecated and removed features, and other changes affecting compatibility:
buggy kernel interfaces (for instance some CIFS version) that could still
see spurious EINTR error when cancellation interrupts a blocking syscall.
+* Previously, glibc installed its various shared objects under versioned
+ file names such as libc-2.33.so. The ABI sonames (e.g., libc.so.6)
+ were provided as symbolic links. Starting with glibc 2.34, the shared
+ objects are installed under their ABI sonames directly, without
+ symbolic links. This increases compatibility with distribution
+ package managers that delete removed files late during the package
+ upgrade or downgrade process.
+
Changes to build and runtime requirements:
* On Linux, the shm_open, sem_open, and related functions now expect the
diff --git a/elf/Makefile b/elf/Makefile
index 62f7e8a225..cdbcc14087 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -630,20 +630,14 @@ $(objpfx)trusted-dirs.st: Makefile $(..)Makeconfig
CPPFLAGS-dl-load.c += -I$(objpfx). -I$(csu-objpfx).
ifeq (yes,$(build-shared))
-$(inst_slibdir)/$(rtld-version-installed-name): $(objpfx)ld.so $(+force)
+$(inst_rtlddir)/$(rtld-installed-name): $(objpfx)ld.so $(+force)
$(make-target-directory)
$(do-install-program)
-$(inst_rtlddir)/$(rtld-installed-name): \
- $(inst_slibdir)/$(rtld-version-installed-name) \
- $(inst_slibdir)/libc-$(version).so
- $(make-target-directory)
- $(make-shlib-link)
-
# Special target called by parent to install just the dynamic linker.
.PHONY: ldso_install
ldso_install: $(inst_rtlddir)/$(rtld-installed-name)
-endif
+endif # $(build-shared)
# Workarounds for ${exec_prefix} expansion in configure variables.
</cut>
Successfully identified regression in *gcc* in CI configuration tcwg_bmk_llvm_tk1/llvm-release-arm-spec2k6-Os. So far, this commit has regressed CI configurations:
- tcwg_bmk_llvm_tk1/llvm-release-arm-spec2k6-Os
Culprit:
<cut>
commit b6bf4d8a773cde07e751542f2911307d78b717fd
Author: Andreas Tobler <andreast(a)gcc.gnu.org>
Date: Thu Apr 25 22:03:35 2019 +0200
freebsd64.h: Add bits for 32-bit multilib support.
2019-04-25 Andreas Tobler <andreast(a)gcc.gnu.org>
* config/i386/freebsd64.h: Add bits for 32-bit multilib support.
* config/i386/t-freebsd64: New file.
* config.gcc: Add the t-freebsd64 for multilib support.
From-SVN: r270586
</cut>
Results regressed to (for first_bad == b6bf4d8a773cde07e751542f2911307d78b717fd)
# 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 -Os_mthumb -- artifacts/build-b6bf4d8a773cde07e751542f2911307d78b717fd/results_id:
1
# 429.mcf,mcf_base.default regressed by 104
# 470.lbm,lbm_base.default regressed by 103
from (for last_good == 8a55f9c57a1ffd900262aa2fc2015822dc059331)
# 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 -Os_mthumb -- artifacts/build-baseline/results_id:
1
Artifacts of last_good build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Results ID of last_good: tk1_32/tcwg_bmk_llvm_tk1/baseline-llvm-release-arm-spec2k6-Os/824
Artifacts of first_bad build: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Results ID of first_bad: tk1_32/tcwg_bmk_llvm_tk1/bisect-llvm-release-arm-spec2k6-Os/929
Build top page/logs: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Configuration details:
Reproduce builds:
<cut>
mkdir investigate-gcc-b6bf4d8a773cde07e751542f2911307d78b717fd
cd investigate-gcc-b6bf4d8a773cde07e751542f2911307d78b717fd
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_tk1-llvm-release… --fail
curl -o artifacts/manifests/build-parameters.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release… --fail
curl -o artifacts/test.sh https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release… --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
cd gcc
# Reproduce first_bad build
git checkout --detach b6bf4d8a773cde07e751542f2911307d78b717fd
../artifacts/test.sh
# Reproduce last_good build
git checkout --detach 8a55f9c57a1ffd900262aa2fc2015822dc059331
../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_tk1-llvm-release…
Build log: https://ci.linaro.org/job/tcwg_bmk_ci_llvm-bisect-tcwg_bmk_tk1-llvm-release…
Full commit (up to 1000 lines):
<cut>
commit b6bf4d8a773cde07e751542f2911307d78b717fd
Author: Andreas Tobler <andreast(a)gcc.gnu.org>
Date: Thu Apr 25 22:03:35 2019 +0200
freebsd64.h: Add bits for 32-bit multilib support.
2019-04-25 Andreas Tobler <andreast(a)gcc.gnu.org>
* config/i386/freebsd64.h: Add bits for 32-bit multilib support.
* config/i386/t-freebsd64: New file.
* config.gcc: Add the t-freebsd64 for multilib support.
From-SVN: r270586
---
gcc/ChangeLog | 6 ++++++
gcc/config.gcc | 5 ++++-
gcc/config/i386/freebsd64.h | 5 ++++-
gcc/config/i386/t-freebsd64 | 30 ++++++++++++++++++++++++++++++
4 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7cd02c850d3..3a927ed00d3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2019-04-25 Andreas Tobler <andreast(a)gcc.gnu.org>
+
+ * config/i386/freebsd64.h: Add bits for 32-bit multilib support.
+ * config/i386/t-freebsd64: New file.
+ * config.gcc: Add the t-freebsd64 for multilib support.
+
2019-04-25 Uroš Bizjak <ubizjak(a)gmail.com>
* doc/extend.texi (vector_size): Add missing comma after @xref.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 09fb9ecd2cd..c7a464c89d0 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4927,7 +4927,10 @@ case ${target} in
;;
i[34567]86-*-dragonfly* | x86_64-*-dragonfly*)
;;
- i[34567]86-*-freebsd* | x86_64-*-freebsd*)
+ i[34567]86-*-freebsd*)
+ ;;
+ x86_64-*-freebsd*)
+ tmake_file="${tmake_file} i386/t-freebsd64"
;;
ia64*-*-linux*)
;;
diff --git a/gcc/config/i386/freebsd64.h b/gcc/config/i386/freebsd64.h
index 1f99e812f01..bffe19c14ff 100644
--- a/gcc/config/i386/freebsd64.h
+++ b/gcc/config/i386/freebsd64.h
@@ -31,7 +31,7 @@ along with GCC; see the file COPYING3. If not see
#undef LINK_SPEC
#define LINK_SPEC "\
- %{m32:-m elf_i386_fbsd} \
+ %{m32:-m elf_i386_fbsd}%{!m32:-m elf_x86_64_fbsd} \
%{p:%nconsider using '-pg' instead of '-p' with gprof(1)} \
%{v:-V} \
%{assert*} %{R*} %{rpath*} %{defsym*} \
@@ -42,3 +42,6 @@ along with GCC; see the file COPYING3. If not see
-dynamic-linker %(fbsd_dynamic_linker) } \
%{static:-Bstatic}} \
%{symbolic:-Bsymbolic}"
+
+#undef MULTILIB_DEFAULTS
+#define MULTILIB_DEFAULTS { "m64" }
diff --git a/gcc/config/i386/t-freebsd64 b/gcc/config/i386/t-freebsd64
new file mode 100644
index 00000000000..0dd05d479ac
--- /dev/null
+++ b/gcc/config/i386/t-freebsd64
@@ -0,0 +1,30 @@
+# Copyright (C) 2019 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC 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, or (at your option)
+# any later version.
+#
+# GCC 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 GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# The 32-bit libraries are found in /usr/lib32
+
+# To support i386 and x86-64, the directory structrue
+# should be:
+#
+# /lib has x86-64 libraries.
+# /lib32 has i386 libraries.
+#
+
+MULTILIB_OPTIONS = m32
+MULTILIB_DIRNAMES = 32
+MULTILIB_OSDIRNAMES = ../lib32
</cut>