]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
LoongArch: Only allow valid binary op when optimize conditional move
authorJinyang He <hejinyang@loongson.cn>
Wed, 29 Oct 2025 08:07:35 +0000 (16:07 +0800)
committerLulu Cheng <chenglulu@loongson.cn>
Fri, 31 Oct 2025 02:10:37 +0000 (10:10 +0800)
It is wrong that optimize from `if (cond) dest op= 1 << shift` to
`dest op= (cond ? 1 : 0) << shift` when `dest op 0 != dest`.
Like `and`, `mul` or `div`.
And in this optimization `mul` and `div` is optimized to shift.

gcc/ChangeLog:

* config/loongarch/loongarch.cc
(loongarch_expand_conditional_move): Only allow valid binary
op when optimize conditional move.

gcc/testsuite/ChangeLog:

* gcc.target/loongarch/conditional-move-opt-1.c: Remove mul.
* gcc.target/loongarch/conditional-move-opt-2.c: Remove and.
* gcc.target/loongarch/conditional-move-opt-3.c: New test.

Co-Authored-By: Peng Fan <fanpeng@loongson.cn>
(cherry picked from commit 824eae920f0f64dd7687c969a2436b129161fdc9)

gcc/config/loongarch/loongarch.cc
gcc/testsuite/gcc.target/loongarch/conditional-move-opt-1.c
gcc/testsuite/gcc.target/loongarch/conditional-move-opt-2.c
gcc/testsuite/gcc.target/loongarch/conditional-move-opt-3.c [new file with mode: 0644]

index 3cfc0cf1b82978b8a8a2d70130243341ece3318f..b3189f3101de601374b4de5388798dcd9f223f2c 100644 (file)
@@ -5437,12 +5437,32 @@ loongarch_expand_conditional_move (rtx *operands)
            }
        }
 
+      auto is_binary_op_0_keep_orig = [](enum rtx_code code)
+       {
+         switch (code)
+           {
+           case PLUS:
+           case MINUS:
+           case IOR:
+           case XOR:
+           case ROTATE:
+           case ROTATERT:
+           case ASHIFT:
+           case ASHIFTRT:
+           case LSHIFTRT:
+             return true;
+           default:
+             return false;
+           }
+       };
+
       /* Check if the optimization conditions are met.  */
       if (value_if_true_insn
          && value_if_false_insn
-         /* Make sure that value_if_false and var are the same.  */
-         && BINARY_P (value_if_true_insn_src
-                      = SET_SRC (single_set (value_if_true_insn)))
+         /* Make sure that the orig value OP 0 keep orig.  */
+         && (value_if_true_insn_src
+             = SET_SRC (single_set (value_if_true_insn)))
+         && is_binary_op_0_keep_orig ( GET_CODE (value_if_true_insn_src))
          /* Make sure that both value_if_true and value_if_false
             has the same var.  */
          && rtx_equal_p (XEXP (value_if_true_insn_src, 0),
index ed13471aa90a0e95a44e71dd1c1adb5520744d9b..47802aa9688de832f57dc1ae1a4c0d9bd8f2220c 100644 (file)
@@ -27,7 +27,7 @@ void
 test_lt ()
 {
   if (lm < ln)
-    lr *= (1 << 16);
+    lr += (1 << 16);
   lr += lm;
 }
 
@@ -35,7 +35,7 @@ void
 test_le ()
 {
   if (lm <= ln)
-    lr = lm * ((long)1 << 32);
+    lr = lm + ((long)1 << 32);
   else
     lr = lm;
   lr += lm;
index ac72d4d933ad493440b16a021c5f826e8d21f503..743fd5e670e25fab8e2ee305a47786126b851492 100644 (file)
@@ -29,7 +29,7 @@ void
 test_lez ()
 {
   if (lm <= 0)
-    lr &= (1 << 16);
+    lr |= (1 << 16);
   lr += lm;
 }
 
diff --git a/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-3.c b/gcc/testsuite/gcc.target/loongarch/conditional-move-opt-3.c
new file mode 100644 (file)
index 0000000..9588798
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "maskeqz" } } */
+/* { dg-final { scan-assembler "masknez" } } */
+
+extern long lm, ln, lr;
+
+void
+test_and ()
+{
+  if (lm < 0)
+    lr &= (1 << 16);
+  lr += lm;
+}