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 /libcpp/errors.c | |
| 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 'libcpp/errors.c')
0 files changed, 0 insertions, 0 deletions
