Re: [PATCH] LoongArch: combine related slli operations

2025-01-07 Thread Zhou Zhao



在 2025/1/7 下午7:49, Lulu Cheng 写道:


在 2025/1/2 下午5:46, Zhou Zhao 写道:

If SImode reg is continuous left shifted twice, combine related
instruction to one.

gcc/ChangeLog:

* config/loongarch/loongarch.md (extsv_ashlsi3):
    New template


Hi, zhaozhou:

The indentation here is wrong, it needs to be aligned with *.


Hi, Lulu cheng:

Thanks for your advice, I have revised.



gcc/testsuite/ChangeLog:

* gcc.target/loongarch/slli-1.c: New test.
---
  gcc/config/loongarch/loongarch.md   | 13 +
  gcc/testsuite/gcc.target/loongarch/slli-1.c | 10 ++
  2 files changed, 23 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/loongarch/slli-1.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md

index 19a22a93de3..1c62e5c02a1 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3048,6 +3048,19 @@ (define_insn "si3_extend"
    [(set_attr "type" "shift")
 (set_attr "mode" "SI")])
  +(define_insn "extsv_ashlsi3"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+    (ashift:DI
+   (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
+    (match_operand:SI 2 "const_uimm5_operand")
+    (const_int 0))
+   (match_operand:SI 3 "const_uimm5_operand")))]
+  "TARGET_64BIT
+    &&(INTVAL (operands[2]) + INTVAL (operands[3])) == 0x20"
+  "slli.w\t%0,%1,%3"
+  [(set_attr "type" "shift")
+   (set_attr "mode" "SI")])
+
  (define_insn "*rotr3"
    [(set (match_operand:GPR 0 "register_operand" "=r,r")
  (rotatert:GPR (match_operand:GPR 1 "register_operand" "r,r")
diff --git a/gcc/testsuite/gcc.target/loongarch/slli-1.c 
b/gcc/testsuite/gcc.target/loongarch/slli-1.c

new file mode 100644
index 000..891d6457b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/slli-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (int x)
+{
+  return (x << 2) * 8;
+}
+
+/* { dg-final { scan-assembler-times "slli\.\[dw\]" 1} } */




Re: [PATCH] match.pd: Fold pattern of round semantics.

2025-01-08 Thread Zhou Zhao



在 2025/1/7 下午10:45, Richard Biener 写道:

On Thu, 2 Jan 2025, 赵洲 wrote:


Add Reviewer Richard Biener.



-原始邮件-
发件人: "Zhou Zhao" 
发送时间:2025-01-02 19:37:07 (星期四)
收件人: gcc-patches@gcc.gnu.org
抄送: xry...@xry111.site, i...@xen0n.name, chengl...@loongson.cn, 
xucheng...@loongson.cn, zhaoz...@loongson.cn
主题: [PATCH] match.pd: Fold pattern of round semantics.

This patch implements 4 rules for semantics of round func in match.pd under
-funsafe-math-optimizations:
1) (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) -> floor(x+0.5)
2) (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) -> floor(x+0.5)
3) (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) -> floor(x+0.5)
4) (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) -> floor(x+0.5)

The patch implements floor(x+0.5) operation to replace semantics of
round(x) function.
The patch was regtested on aarch64-linux-gnu and x86_64-linux-gnu, SPEC
2017 and SPEC 2006 were run:
As for SPEC 2017, 538.imagick_r benchmark performance increased by 3%+
in base test of ratio mode.
As for SPEC 2006, while the transform does not seem to be triggered, we
also see no non-noise impact on performance.
OK for mainline?

gcc/ChangeLog:

* match.pd: Add new pattern for round.

gcc/testsuite/ChangeLog:

* gcc.dg/fold-round-1.c: New test.
---
  gcc/match.pd| 27 ++
  gcc/testsuite/gcc.dg/fold-round-1.c | 56 +
  2 files changed, 83 insertions(+)
  create mode 100644 gcc/testsuite/gcc.dg/fold-round-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 83eca8b2e0a..7b22b7913ac 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -777,6 +777,33 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
   (rdiv @0 (negate @1))
   (rdiv (negate @0) @1))
  
+(if (flag_unsafe_math_optimizations)

+/* convert semantics of round(x) function to floor(x+0.5) */
+/* (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) --> floor(x+0.5) */
+/* (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) --> floor(x+0.5) */
+/* (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) --> floor(x+0.5) */
+/* (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) --> floor(x+0.5) */


Hi, Richard

Thanks for your reply. This patch is not fixes a bug. If we can discuss

and reach a conclusion now, I will be re-posted/pinged when stage1 opens

for GCC 16.

Zhou Zhao.

I think you should be able to merge the cases for swapped compares
by just matching (cond (op:c (...)).


If use swapped compares to merge the cases, the expression

((x - floor(x)) < (ceil(x) - x) ? floor(x) : ceil(x)) can be transformed to

((ceil(x) - x) < (x - floor(x)) ? floor(x) : ceil(x)), this is not the 
expression


I want, not be simplified to floor(x + 0.5). For example, when x = 1.4

the result of new expression is ceil(1.4)=2.0, but floor(1.4+0.5)=1.0.

So I did not use swapped compares to merge the cases.


I do wonder about the compares itself though, (x-floor(x)) < (ceil(x)-x)
isn't that true exactly when x > 0?  With flag_unsafe_optimizations
< vs. <= and thus x not having a fractional component would be
unimportant.  That said, wouldn't we expect the compares to be
simplified?


I agree your said, this expression can be simplified when x not haveing a

fractional component, but it's difficult to determine whether x having a

fractional component. Maybe constrain x is int type and matching

(floor (float@1 @0)) can simplify the expression. But that's not my purpose,

maybe the commits is not clear enough, I would rephrase it.

We only need to focus on the first pattern,the other three are different

forms of it. I will use "left distance" to represent the distance from x

to its left integer boundary, "right distance" to represent the distance

from x to its right integer boundary.

The pattern semantics as follows:

as for x, if left distance is less than right distance, return floor(x),

if left distance is greater or equal than right distance, return ceil(x).

For example, when x=1.4, the left distance is less than right distance,

return floor(x). (x+0.5) has not crossed the right boundary. floor(x+0.5)

is equal to floor(x). when x=1.5 or x=1.6, the left distance is not less

than right distance, return ceil(x). (x+0.5) has crossed the right

boundary. floor(x+0.5) is equal to ceil(x).


I'm also curious where you got these expressions to be simplified from?


In the 538.imagick_r benchmark of Spec2017, I find this pattern from

MagickRound function. By simplifying the pattern, the performance of the

538 benchmark can be improved by 3% to 4% on aarch64-linux-gnu and

x86_64-linux-gnu.


Note we're in stage3 so unless this fixes a bug it isn't appropriate
at this stage and should be re-posted/pinged when stage1 opens for
GCC 16.

Richard.


+(for op (lt ge)
+ bt (FLOOR CEIL)
+ bf (CEIL FLOOR)
+ floor (FLOOR FLOOR)
+ ceil (CEIL CEIL)
+ (simplify
+

[PATCH] LoongArch: combine related slli operations

2025-01-02 Thread Zhou Zhao
If SImode reg is continuous left shifted twice, combine related
instruction to one.

gcc/ChangeLog:

* config/loongarch/loongarch.md (extsv_ashlsi3):
  New template

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/slli-1.c: New test.
---
 gcc/config/loongarch/loongarch.md   | 13 +
 gcc/testsuite/gcc.target/loongarch/slli-1.c | 10 ++
 2 files changed, 23 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/slli-1.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md
index 19a22a93de3..1c62e5c02a1 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3048,6 +3048,19 @@ (define_insn "si3_extend"
   [(set_attr "type" "shift")
(set_attr "mode" "SI")])
 
+(define_insn "extsv_ashlsi3"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+   (ashift:DI
+  (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
+   (match_operand:SI 2 "const_uimm5_operand")
+   (const_int 0))
+  (match_operand:SI 3 "const_uimm5_operand")))]
+  "TARGET_64BIT
+&&(INTVAL (operands[2]) + INTVAL (operands[3])) == 0x20"
+  "slli.w\t%0,%1,%3"
+  [(set_attr "type" "shift")
+   (set_attr "mode" "SI")])
+
 (define_insn "*rotr3"
   [(set (match_operand:GPR 0 "register_operand" "=r,r")
(rotatert:GPR (match_operand:GPR 1 "register_operand" "r,r")
diff --git a/gcc/testsuite/gcc.target/loongarch/slli-1.c 
b/gcc/testsuite/gcc.target/loongarch/slli-1.c
new file mode 100644
index 000..891d6457b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/slli-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (int x)
+{
+  return (x << 2) * 8;
+}
+
+/* { dg-final { scan-assembler-times "slli\.\[dw\]" 1} } */
-- 
2.20.1



Re: [PATCH] match.pd: Fold pattern of round semantics.

2025-01-08 Thread Zhou Zhao



在 2025/1/8 下午5:04, Richard Biener 写道:

On Wed, 8 Jan 2025, Zhou Zhao wrote:


在 2025/1/7 下午10:45, Richard Biener 写道:

On Thu, 2 Jan 2025, 赵洲 wrote:


Add Reviewer Richard Biener.



-原始邮件-
发件人: "Zhou Zhao" 
发送时间:2025-01-02 19:37:07 (星期四)
收件人: gcc-patches@gcc.gnu.org
抄送: xry...@xry111.site, i...@xen0n.name, chengl...@loongson.cn,
xucheng...@loongson.cn, zhaoz...@loongson.cn
主题: [PATCH] match.pd: Fold pattern of round semantics.

This patch implements 4 rules for semantics of round func in match.pd
under
-funsafe-math-optimizations:
1) (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) -> floor(x+0.5)
2) (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) -> floor(x+0.5)
3) (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) -> floor(x+0.5)
4) (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) -> floor(x+0.5)

The patch implements floor(x+0.5) operation to replace semantics of
round(x) function.
The patch was regtested on aarch64-linux-gnu and x86_64-linux-gnu, SPEC
2017 and SPEC 2006 were run:
As for SPEC 2017, 538.imagick_r benchmark performance increased by 3%+
in base test of ratio mode.
As for SPEC 2006, while the transform does not seem to be triggered, we
also see no non-noise impact on performance.
OK for mainline?

gcc/ChangeLog:

  * match.pd: Add new pattern for round.

gcc/testsuite/ChangeLog:

* gcc.dg/fold-round-1.c: New test.
---
   gcc/match.pd| 27 ++
   gcc/testsuite/gcc.dg/fold-round-1.c | 56 +
   2 files changed, 83 insertions(+)
   create mode 100644 gcc/testsuite/gcc.dg/fold-round-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 83eca8b2e0a..7b22b7913ac 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -777,6 +777,33 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(rdiv @0 (negate @1))
(rdiv (negate @0) @1))
   +(if (flag_unsafe_math_optimizations)
+/* convert semantics of round(x) function to floor(x+0.5) */
+/* (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) --> floor(x+0.5) */
+/* (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) --> floor(x+0.5) */
+/* (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) --> floor(x+0.5) */
+/* (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) --> floor(x+0.5) */

Hi, Richard

Thanks for your reply. This patch is not fixes a bug. If we can discuss

and reach a conclusion now, I will be re-posted/pinged when stage1 opens

for GCC 16.

Zhou Zhao.

I think you should be able to merge the cases for swapped compares
by just matching (cond (op:c (...)).

If use swapped compares to merge the cases, the expression

((x - floor(x)) < (ceil(x) - x) ? floor(x) : ceil(x)) can be transformed to

((ceil(x) - x) < (x - floor(x)) ? floor(x) : ceil(x)), this is not the
expression

I want, not be simplified to floor(x + 0.5). For example, when x = 1.4

the result of new expression is ceil(1.4)=2.0, but floor(1.4+0.5)=1.0.

So I did not use swapped compares to merge the cases.

The swapped compare will match

(ceil(x) - x) > (x - floor(x) ? floor(x) : ceil(x)


Ah, you are correct. I try use the swapped compares merge the cases, it's

consistent with what you said. I misunderstood the swapped comparison 
symbols.



I do wonder about the compares itself though, (x-floor(x)) < (ceil(x)-x)
isn't that true exactly when x > 0?  With flag_unsafe_optimizations
< vs. <= and thus x not having a fractional component would be
unimportant.  That said, wouldn't we expect the compares to be
simplified?

I agree your said, this expression can be simplified when x not haveing a

fractional component, but it's difficult to determine whether x having a

fractional component. Maybe constrain x is int type and matching

(floor (float@1 @0)) can simplify the expression. But that's not my purpose,

maybe the commits is not clear enough, I would rephrase it.

We only need to focus on the first pattern,the other three are different

forms of it. I will use "left distance" to represent the distance from x

to its left integer boundary, "right distance" to represent the distance

from x to its right integer boundary.

The pattern semantics as follows:

as for x, if left distance is less than right distance, return floor(x),

if left distance is greater or equal than right distance, return ceil(x).

For example, when x=1.4, the left distance is less than right distance,

return floor(x). (x+0.5) has not crossed the right boundary. floor(x+0.5)

is equal to floor(x). when x=1.5 or x=1.6, the left distance is not less

than right distance, return ceil(x). (x+0.5) has crossed the right

boundary. floor(x+0.5) is equal to ceil(x).

I see.  So how does it relate to rint/nearbyint?


rint funciton is round halfway cases to the even integer. like 
rint(0.5)=0.0,


but this pattern of we mentioned is result 1.0.


I'm also curious where you got these expressions to be simplified from?

In the 538.imagick

Re: [PATCH] match.pd: Fold pattern of round semantics.

2025-01-09 Thread Zhou Zhao



在 2025/1/9 下午3:33, Richard Biener 写道:

On Thu, 9 Jan 2025, Zhou Zhao wrote:


在 2025/1/8 下午6:30, Richard Biener 写道:

On Wed, 8 Jan 2025, Zhou Zhao wrote:


在 2025/1/8 下午5:04, Richard Biener 写道:

On Wed, 8 Jan 2025, Zhou Zhao wrote:


在 2025/1/7 下午10:45, Richard Biener 写道:

On Thu, 2 Jan 2025, 赵洲 wrote:


Add Reviewer Richard Biener.



-原始邮件-
发件人: "Zhou Zhao" 
发送时间:2025-01-02 19:37:07 (星期四)
收件人: gcc-patches@gcc.gnu.org
抄送: xry...@xry111.site, i...@xen0n.name, chengl...@loongson.cn,
xucheng...@loongson.cn, zhaoz...@loongson.cn
主题: [PATCH] match.pd: Fold pattern of round semantics.

This patch implements 4 rules for semantics of round func in match.pd
under
-funsafe-math-optimizations:
1) (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) -> floor(x+0.5)
2) (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) -> floor(x+0.5)
3) (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) -> floor(x+0.5)
4) (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) -> floor(x+0.5)

The patch implements floor(x+0.5) operation to replace semantics of
round(x) function.
The patch was regtested on aarch64-linux-gnu and x86_64-linux-gnu,
SPEC
2017 and SPEC 2006 were run:
As for SPEC 2017, 538.imagick_r benchmark performance increased by 3%+
in base test of ratio mode.
As for SPEC 2006, while the transform does not seem to be triggered,
we
also see no non-noise impact on performance.
OK for mainline?

gcc/ChangeLog:

* match.pd: Add new pattern for round.

gcc/testsuite/ChangeLog:

* gcc.dg/fold-round-1.c: New test.
---
 gcc/match.pd| 27 ++
 gcc/testsuite/gcc.dg/fold-round-1.c | 56
 +
 2 files changed, 83 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/fold-round-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 83eca8b2e0a..7b22b7913ac 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -777,6 +777,33 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (rdiv @0 (negate @1))
  (rdiv (negate @0) @1))
 +(if (flag_unsafe_math_optimizations)
+/* convert semantics of round(x) function to floor(x+0.5) */
+/* (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) --> floor(x+0.5)
*/
+/* (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) --> floor(x+0.5)
*/
+/* (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) --> floor(x+0.5)
*/
+/* (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) --> floor(x+0.5)
*/

Hi, Richard

Thanks for your reply. This patch is not fixes a bug. If we can discuss

and reach a conclusion now, I will be re-posted/pinged when stage1 opens

for GCC 16.

Zhou Zhao.

I think you should be able to merge the cases for swapped compares
by just matching (cond (op:c (...)).

If use swapped compares to merge the cases, the expression

((x - floor(x)) < (ceil(x) - x) ? floor(x) : ceil(x)) can be transformed
to

((ceil(x) - x) < (x - floor(x)) ? floor(x) : ceil(x)), this is not the
expression

I want, not be simplified to floor(x + 0.5). For example, when x = 1.4

the result of new expression is ceil(1.4)=2.0, but floor(1.4+0.5)=1.0.

So I did not use swapped compares to merge the cases.

The swapped compare will match

(ceil(x) - x) > (x - floor(x) ? floor(x) : ceil(x)

Ah, you are correct. I try use the swapped compares merge the cases, it's

consistent with what you said. I misunderstood the swapped comparison
symbols.


I do wonder about the compares itself though, (x-floor(x)) < (ceil(x)-x)
isn't that true exactly when x > 0?  With flag_unsafe_optimizations
< vs. <= and thus x not having a fractional component would be
unimportant.  That said, wouldn't we expect the compares to be
simplified?

I agree your said, this expression can be simplified when x not haveing a

fractional component, but it's difficult to determine whether x having a

fractional component. Maybe constrain x is int type and matching

(floor (float@1 @0)) can simplify the expression. But that's not my
purpose,

maybe the commits is not clear enough, I would rephrase it.

We only need to focus on the first pattern,the other three are different

forms of it. I will use "left distance" to represent the distance from x

to its left integer boundary, "right distance" to represent the distance

from x to its right integer boundary.

The pattern semantics as follows:

as for x, if left distance is less than right distance, return floor(x),

if left distance is greater or equal than right distance, return ceil(x).

For example, when x=1.4, the left distance is less than right distance,

return floor(x). (x+0.5) has not crossed the right boundary. floor(x+0.5)

is equal to floor(x). when x=1.5 or x=1.6, the left distance is not less

than right distance, return ceil(x). (x+0.5) has crossed the right

boundary. floor(x+0.5) is equal to ceil(x).

I see.  So how does it relate to rint/nearbyint?

rint funciton is round halfway cases to the even integer. li

[PATCH] match.pd: Fold pattern of round semantics.

2025-01-02 Thread Zhou Zhao
This patch implements 4 rules for semantics of round func in match.pd under
-funsafe-math-optimizations:
1) (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) -> floor(x+0.5)
2) (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) -> floor(x+0.5)
3) (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) -> floor(x+0.5)
4) (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) -> floor(x+0.5)

The patch implements floor(x+0.5) operation to replace semantics of
round(x) function.
The patch was regtested on aarch64-linux-gnu and x86_64-linux-gnu, SPEC
2017 and SPEC 2006 were run:
As for SPEC 2017, 538.imagick_r benchmark performance increased by 3%+
in base test of ratio mode.
As for SPEC 2006, while the transform does not seem to be triggered, we
also see no non-noise impact on performance.
OK for mainline?

gcc/ChangeLog:

* match.pd: Add new pattern for round.

gcc/testsuite/ChangeLog:

* gcc.dg/fold-round-1.c: New test.
---
 gcc/match.pd| 27 ++
 gcc/testsuite/gcc.dg/fold-round-1.c | 56 +
 2 files changed, 83 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/fold-round-1.c

diff --git a/gcc/match.pd b/gcc/match.pd
index 83eca8b2e0a..7b22b7913ac 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -777,6 +777,33 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
  (rdiv @0 (negate @1))
  (rdiv (negate @0) @1))
 
+(if (flag_unsafe_math_optimizations)
+/* convert semantics of round(x) function to floor(x+0.5) */
+/* (x-floor(x)) < (ceil(x)-x) ? floor(x) : ceil(x) --> floor(x+0.5) */
+/* (x-floor(x)) >= (ceil(x)-x) ? ceil(x) : floor(x) --> floor(x+0.5) */
+/* (ceil(x)-x) > (x-floor(x)) ? floor(x) : ceil(x) --> floor(x+0.5) */
+/* (ceil(x)-x) <= (x-floor(x)) ? ceil(x) : floor(x) --> floor(x+0.5) */
+(for op (lt ge)
+ bt (FLOOR CEIL)
+ bf (CEIL FLOOR)
+ floor (FLOOR FLOOR)
+ ceil (CEIL CEIL)
+ (simplify
+  (cond (op (minus:s SSA_NAME@0 (floor SSA_NAME@0))
+   (minus:s (ceil SSA_NAME@0) SSA_NAME@0))
+   (bt SSA_NAME@0) (bf SSA_NAME@0))
+  (floor (plus @0 { build_real (type, dconsthalf); }
+(for op (gt le)
+ bt (FLOOR CEIL)
+ bf (CEIL FLOOR)
+ floor (FLOOR FLOOR)
+ ceil (CEIL CEIL)
+ (simplify
+  (cond (op (minus:s (ceil SSA_NAME@0) SSA_NAME@0)
+   (minus:s SSA_NAME@0 (floor SSA_NAME@0)))
+   (bt SSA_NAME@0) (bf SSA_NAME@0))
+  (floor (plus @0 { build_real (type, dconsthalf); })
+
 (if (flag_unsafe_math_optimizations)
  /* Simplify (C / x op 0.0) to x op 0.0 for C != 0, C != Inf/Nan.
 Since C / x may underflow to zero, do this only for unsafe math.  */
diff --git a/gcc/testsuite/gcc.dg/fold-round-1.c 
b/gcc/testsuite/gcc.dg/fold-round-1.c
new file mode 100644
index 000..845d6d2e475
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-round-1.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -funsafe-math-optimizations" } */
+
+extern void link_error (void);
+
+#define TEST_ROUND(TYPE, FFLOOR, FCEIL)   \
+  void round_##FFLOOR##_1 (TYPE x)\
+  {   \
+TYPE t1 = 0;  \
+TYPE t2 = __builtin_##FFLOOR (x + 0.5);   \
+if ((x - __builtin_##FFLOOR (x)) < (__builtin_##FCEIL (x) - x))   \
+  t1 = __builtin_##FFLOOR (x);\
+else  \
+  t1 = __builtin_##FCEIL (x); \
+if (t1 != t2) \
+  link_error ();  \
+  }   \
+  void round_##FFLOOR##_2 (TYPE x)\
+  {   \
+TYPE t1 = 0;  \
+TYPE t2 = __builtin_##FFLOOR (x + 0.5);   \
+if ((__builtin_##FCEIL (x) - x) > (x - __builtin_##FFLOOR (x)))   \
+  t1 = __builtin_##FFLOOR (x);\
+else  \
+  t1 = __builtin_##FCEIL (x); \
+if (t1 != t2) \
+  link_error ();  \
+  }   \
+  void round_##FFLOOR##_3 (TYPE x)\
+  {   \
+TYPE t1 = 0;  

Ping: [PATCH] LoongArch: combine related slli operations

2025-03-10 Thread Zhou Zhao

Ping

在 2025/1/7 下午8:45, Zhou Zhao 写道:


在 2025/1/7 下午7:49, Lulu Cheng 写道:


在 2025/1/2 下午5:46, Zhou Zhao 写道:

If SImode reg is continuous left shifted twice, combine related
instruction to one.

gcc/ChangeLog:

* config/loongarch/loongarch.md (extsv_ashlsi3):
    New template


Hi, zhaozhou:

The indentation here is wrong, it needs to be aligned with *.


Hi, Lulu cheng:

Thanks for your advice, I have revised.



gcc/testsuite/ChangeLog:

* gcc.target/loongarch/slli-1.c: New test.
---
  gcc/config/loongarch/loongarch.md   | 13 +
  gcc/testsuite/gcc.target/loongarch/slli-1.c | 10 ++
  2 files changed, 23 insertions(+)
  create mode 100644 gcc/testsuite/gcc.target/loongarch/slli-1.c

diff --git a/gcc/config/loongarch/loongarch.md 
b/gcc/config/loongarch/loongarch.md

index 19a22a93de3..1c62e5c02a1 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -3048,6 +3048,19 @@ (define_insn "si3_extend"
    [(set_attr "type" "shift")
 (set_attr "mode" "SI")])
  +(define_insn "extsv_ashlsi3"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+    (ashift:DI
+   (sign_extract:DI (match_operand:DI 1 "register_operand" "r")
+    (match_operand:SI 2 "const_uimm5_operand")
+    (const_int 0))
+   (match_operand:SI 3 "const_uimm5_operand")))]
+  "TARGET_64BIT
+    &&(INTVAL (operands[2]) + INTVAL (operands[3])) == 0x20"
+  "slli.w\t%0,%1,%3"
+  [(set_attr "type" "shift")
+   (set_attr "mode" "SI")])
+
  (define_insn "*rotr3"
    [(set (match_operand:GPR 0 "register_operand" "=r,r")
  (rotatert:GPR (match_operand:GPR 1 "register_operand" "r,r")
diff --git a/gcc/testsuite/gcc.target/loongarch/slli-1.c 
b/gcc/testsuite/gcc.target/loongarch/slli-1.c

new file mode 100644
index 000..891d6457b12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/slli-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (int x)
+{
+  return (x << 2) * 8;
+}
+
+/* { dg-final { scan-assembler-times "slli\.\[dw\]" 1} } */