LoongArch: Fix uint64_t a & 0xfffffffffff on LA32

"uint64_t a & 0xfffffffffff" expands to two and:SI on LA32 with -O0:

(insn 8 7 9 (set (subreg:SI (reg:DI 82 [ a_2 ]) 0)
         (and:SI (reg:SI 83)
             (const_int -1 [0xffffffffffffffff]))) "t.c":3:5 -1
      (nil))
(insn 10 9 11 (set (subreg:SI (reg:DI 82 [ a_2 ]) 4)
        (and:SI (reg:SI 84)
            (const_int 4095 [0xfff]))) "t.c":3:5 -1
     (nil))

"insn 8" -1 operand can't match Yx constraint low_bitmask_len condition.

low_bitmask_len can selects a field of low-order bits within an item but not
the entire word. Add (match_test "INTVAL (op) == -1") to low_bitmask_operand
predicate.

Note: "uint64_t a & 0xffffffffffffffff" and "uint32_t a & 0xffffffff" are
optimized away before expand with -O0, can't cause this error.

gcc/ChangeLog:

	* config/loongarch/predicates.md: Add CONSTM1_RTX for low_bitmask_operand.

gcc/testsuite/ChangeLog:

	* gcc.target/loongarch/la32/and.c: New test.
	* gcc.target/loongarch/la32/la32.exp: New test.

Reviewed-by: Xi Ruoyao <xry111@xry111.site>
Reviewed-by: Lulu Cheng <chenglulu@loongson.cn>
This commit is contained in:
mengqinggang
2025-11-19 14:19:39 +08:00
committed by Lulu Cheng
parent a79d9b6dbf
commit bc3a77cdcd
3 changed files with 51 additions and 1 deletions

View File

@@ -295,7 +295,9 @@
(define_predicate "low_bitmask_operand"
(and (match_code "const_int")
(match_test "low_bitmask_len (mode, INTVAL (op)) > 12")
(ior
(match_test "low_bitmask_len (mode, INTVAL (op)) > 12")
(match_test "op == CONSTM1_RTX (GET_MODE (op))"))
(match_test "!TARGET_32BIT_R")))
(define_predicate "d_operand"

View File

@@ -0,0 +1,8 @@
/* { dg-do compile } */
/* { dg-options "-O0" } */
#include <stdint.h>
uint64_t f(uint64_t a) {
a = a & 0xfffffffffffff;
return a;
}

View File

@@ -0,0 +1,40 @@
# Copyright (C) 2021-2025 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
# GCC testsuite that uses the `dg.exp' driver.
# Exit immediately if this isn't a LoongArch target.
if ![istarget loongarch32*-*-*] then {
return
}
# Load support procs.
load_lib gcc-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
set DEFAULT_CFLAGS " "
}
# Initialize `dg'.
dg-init
# Main loop.
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
"" $DEFAULT_CFLAGS
# All done.
dg-finish