diff options
author | Takayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp> | 2025-08-29 19:19:32 +0900 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2025-08-31 16:39:01 -0700 |
commit | 4553eccd23d74ba9ad2f862c5e66278a21abfe49 (patch) | |
tree | 7aff59fd7884901e5e604623da6dfbdbf7a41a26 /libgomp/testsuite/libgomp.fortran/target-simd.f90 | |
parent | d21f10259f64723f8deae3bccc15128075de4851 (diff) | |
download | gcc-4553eccd23d74ba9ad2f862c5e66278a21abfe49.zip gcc-4553eccd23d74ba9ad2f862c5e66278a21abfe49.tar.gz gcc-4553eccd23d74ba9ad2f862c5e66278a21abfe49.tar.bz2 |
xtensa: Optimize branch whether (reg:SI) is within/out the range handled by CLAMPS instruction
The CLAMPS instruction in Xtensa ISA, provided when the TARGET_CLAMPS
configuration is enabled (and also requires TARGET_MINMAX), returns a
value clamped the number in the specified register to between -(1<<N) and
(1<<N)-1 inclusive, where N is an immediate value from 7 to 22.
Therefore, when the above configurations are met, by comparing the clamped
result with the original value for equality, branching whether the value
is within the range mentioned above or not is implemented with fewer
instructions, especially when the upper and lower bounds of the range are
too large to fit into a single immediate assignment.
/* example (TARGET_MINMAX and TARGET_CLAMPS) */
extern void foo(void);
void test0(int a) {
if (a >= -(1 << 9) && a < (1 << 9))
foo();
}
void test1(int a) {
if (a < -(1 << 20) || a >= (1 << 20))
foo();
}
;; before
test0:
entry sp, 32
addmi a2, a2, 0x200
movi a8, 0x3ff
bltu a8, a2, .L1
call8 foo
.L1:
retw.n
test1:
entry sp, 32
movi.n a9, 1
movi.n a8, -1
slli a9, a9, 20
srli a8, a8, 11
add.n a2, a2, a9
bgeu a8, a2, .L4
call8 foo
.L4:
retw.n
;; after
test0:
entry sp, 32
clamps a8, a2, 9
bne a2, a8, .L1
call8 foo
.L1:
retw.n
test1:
entry sp, 32
clamps a8, a2, 20
beq a2, a8, .L4
call8 foo
.L4:
retw.n
(note: Currently, in the RTL instruction combination pass, the possible
const_int values are fundamentally constrained by
TARGET_LEGITIMATE_CONSTANT_P() if no bare large constant assignments are
possible (i.e., neither -mconst16 nor -mauto-litpools), so limiting N to
a range of 7 to only 10 instead of to 22. A series of forthcoming
patches will introduce an entirely new "xt_largeconst" pass that will
solve several issues including this.)
gcc/ChangeLog:
* config/xtensa/predicates.md (alt_ubranch_operator):
New predicate.
* config/xtensa/xtensa.md (*eqne_in_range):
New insn_and_split pattern.
Diffstat (limited to 'libgomp/testsuite/libgomp.fortran/target-simd.f90')
0 files changed, 0 insertions, 0 deletions