On Fri, Aug 29, 2025 at 3:19 AM Takayuki 'January June' Suwa
<[email protected]> wrote:
>
> 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.
> ---
>   gcc/config/xtensa/predicates.md |  3 +++
>   gcc/config/xtensa/xtensa.md     | 36 +++++++++++++++++++++++++++++++++
>   2 files changed, 39 insertions(+)

Regtested for target=xtensa-linux-uclibc, no new regressions.
Committed to master.

-- 
Thanks.
-- Max

Reply via email to