mirror of git://gcc.gnu.org/git/gcc.git
Merge branch 'releases/gcc-15' into devel/omp/gcc-15
Merge up to r15-10483-gcc39aed963b5c6 (5 Nov 2025)
This commit is contained in:
commit
6816d10a43
103
gcc/ChangeLog
103
gcc/ChangeLog
|
|
@ -1,3 +1,106 @@
|
|||
2025-11-03 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-01 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
PR rtl-optimization/122321
|
||||
* lra-constraints.cc (update_equiv): Make sure REGNO is in
|
||||
ira_reg_equiv before trying to update ira_reg_equiv.
|
||||
|
||||
2025-11-03 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-26 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
|
||||
|
||||
PR target/122270
|
||||
* config/riscv/riscv-vector-builtins-bases.cc (vset::fold): Use the
|
||||
unshare_expr for the statement that will be added seperately rather
|
||||
the one which will be used for the replacement.
|
||||
|
||||
2025-11-02 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
Backported from master:
|
||||
2025-11-02 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
PR target/122527
|
||||
* config/avr/avr.cc (avr_load_libgcc_p): Return false if
|
||||
the address-space is not ADDR_SPACE_FLASH.
|
||||
(avr_out_lpm_no_lpmx [addr=REG]): Handle sizes of 3 and 4 bytes.
|
||||
|
||||
2025-11-02 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
Backported from master:
|
||||
2025-11-02 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
PR tree-optimization/118012
|
||||
PR tree-optimization/122505
|
||||
* config/avr/avr.md (mulpsi3): Also allow the insn condition
|
||||
in the case where avropt_pr118012 && !AVR_TINY.
|
||||
(*mulpsi3): Handle split for the !AVR_HAVE_MUL case.
|
||||
(*mulpsi3-nomul.libgcc_split, *mulpsi3-nomul.libgcc): New insns.
|
||||
|
||||
2025-10-31 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-27 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
PR tree-optimization/122408
|
||||
* tree-vect-slp-patterns.cc (vect_validate_multiplication): Cleanup and
|
||||
document interface.
|
||||
(complex_mul_pattern::matches, complex_fms_pattern::matches): Update to
|
||||
new interface.
|
||||
|
||||
2025-10-31 Jinyang He <hejinyang@loongson.cn>
|
||||
|
||||
Backported from master:
|
||||
2025-10-30 Jinyang He <hejinyang@loongson.cn>
|
||||
Peng Fan <fanpeng@loongson.cn>
|
||||
|
||||
* config/loongarch/loongarch.cc
|
||||
(loongarch_expand_conditional_move): Only allow valid binary
|
||||
op when optimize conditional move.
|
||||
|
||||
2025-10-30 Guo Jie <guojie@loongson.cn>
|
||||
|
||||
Backported from master:
|
||||
2025-10-30 Guo Jie <guojie@loongson.cn>
|
||||
|
||||
* config/loongarch/lasx.md (fnma<mode>4): Remove.
|
||||
* config/loongarch/lsx.md (fnma<mode>4): Remove.
|
||||
* config/loongarch/simd.md (fnma<mode>4): Simplify and correct.
|
||||
|
||||
2025-10-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/122394
|
||||
* tree-ssa-phiopt.cc (spaceship_replacement): Use
|
||||
build_debug_expr_decl instead of manually building DEBUG_EXPR_DECL
|
||||
and getting SET_DECL_MODE wrong.
|
||||
|
||||
2025-10-27 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-13 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
PR target/120674
|
||||
* config/riscv/riscv.cc (riscv_dwarf_poly_indeterminite_value): Do not
|
||||
set FACTOR to zero, for that case use one instead.
|
||||
|
||||
2025-10-27 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-17 Tamar Christina <tamar.christina@arm.com>
|
||||
Jennifer Schmitz <jschmitz@nvidia.com>
|
||||
|
||||
PR target/121604
|
||||
* config/aarch64/aarch64-sve-builtins-shapes.cc (apply_predication):
|
||||
Store gp_index.
|
||||
(struct pmov_to_vector_lane_def): Mark instruction as has no GP.
|
||||
* config/aarch64/aarch64-sve-builtins.h (function_instance::gp_value,
|
||||
function_instance::inactive_values, function_instance::gp_index,
|
||||
function_shape::has_gp_argument_p): New.
|
||||
* config/aarch64/aarch64-sve-builtins.cc (gimple_folder::fold_pfalse):
|
||||
Simplify code and use GP helpers.
|
||||
|
||||
2025-10-26 LIU Hao <lh_mouse@126.com>
|
||||
|
||||
Backported from master:
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
20251027
|
||||
20251105
|
||||
|
|
|
|||
|
|
@ -1,3 +1,14 @@
|
|||
2025-11-04 Bob Duff <duff@adacore.com>
|
||||
|
||||
PR ada/118208
|
||||
* exp_ch5.adb
|
||||
(Expand_Assign_With_Target_Names.Replace_Target):
|
||||
Remove code setting Entity to Empty.
|
||||
* sinfo.ads (Has_Target_Names):
|
||||
Improve comment: add "@" to clarify what "target name"
|
||||
means, and remove the content-free phrase "and must
|
||||
be expanded accordingly."
|
||||
|
||||
2025-10-24 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR ada/118782
|
||||
|
|
|
|||
|
|
@ -2254,7 +2254,8 @@ package body Exp_Ch5 is
|
|||
function Replace_Target (N : Node_Id) return Traverse_Result;
|
||||
-- Replace occurrences of the target name by the proper entity: either
|
||||
-- the entity of the LHS in simple cases, or the formal of the
|
||||
-- constructed procedure otherwise.
|
||||
-- constructed procedure otherwise. Mark all nodes as Analyzed=False
|
||||
-- so reanalysis will occur.
|
||||
|
||||
--------------------
|
||||
-- Replace_Target --
|
||||
|
|
@ -2264,20 +2265,6 @@ package body Exp_Ch5 is
|
|||
begin
|
||||
if Nkind (N) = N_Target_Name then
|
||||
Rewrite (N, New_Occurrence_Of (Ent, Sloc (N)));
|
||||
|
||||
-- The expression will be reanalyzed when the enclosing assignment
|
||||
-- is reanalyzed, so reset the entity, which may be a temporary
|
||||
-- created during analysis, e.g. a loop variable for an iterated
|
||||
-- component association. However, if entity is callable then
|
||||
-- resolution has established its proper identity (including in
|
||||
-- rewritten prefixed calls) so we must preserve it.
|
||||
|
||||
elsif Is_Entity_Name (N) then
|
||||
if Present (Entity (N))
|
||||
and then not Is_Overloadable (Entity (N))
|
||||
then
|
||||
Set_Entity (N, Empty);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
Set_Analyzed (N, False);
|
||||
|
|
|
|||
|
|
@ -1477,7 +1477,7 @@ package Sinfo is
|
|||
|
||||
-- Has_Target_Names
|
||||
-- Present in assignment statements. Indicates that the RHS contains
|
||||
-- target names (see AI12-0125-3) and must be expanded accordingly.
|
||||
-- target names ("@" -- see AI12-0125-3).
|
||||
|
||||
-- Has_Wide_Character
|
||||
-- Present in string literals, set if any wide character (i.e. character
|
||||
|
|
|
|||
|
|
@ -21,7 +21,10 @@
|
|||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "basic-block.h"
|
||||
#include "tree.h"
|
||||
#include "function.h"
|
||||
#include "gimple.h"
|
||||
#include "rtl.h"
|
||||
#include "tm_p.h"
|
||||
#include "memmodel.h"
|
||||
|
|
@ -68,25 +71,38 @@ za_group_is_pure_overload (const function_group_info &group)
|
|||
types in ARGUMENT_TYPES. RETURN_TYPE is the type returned by the
|
||||
function. */
|
||||
static void
|
||||
apply_predication (const function_instance &instance, tree return_type,
|
||||
apply_predication (function_instance &instance, tree return_type,
|
||||
vec<tree> &argument_types)
|
||||
{
|
||||
/* Initially mark the function as not being predicated. */
|
||||
instance.gp_index = -1;
|
||||
|
||||
/* There are currently no SME ZA instructions that have both merging and
|
||||
unpredicated forms, so for simplicity, the predicates are always included
|
||||
in the original format string. */
|
||||
if (instance.pred != PRED_none && instance.pred != PRED_za_m)
|
||||
{
|
||||
argument_types.quick_insert (0, instance.gp_type ());
|
||||
instance.gp_index = 0;
|
||||
/* For unary merge operations, the first argument is a vector with
|
||||
the same type as the result. For unary_convert_narrowt it also
|
||||
provides the "bottom" half of active elements, and is present
|
||||
for all types of predication. */
|
||||
auto nargs = argument_types.length () - 1;
|
||||
if (instance.shape->has_merge_argument_p (instance, nargs))
|
||||
{
|
||||
argument_types.quick_insert (0, return_type);
|
||||
instance.gp_index = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* In this case the predicate type we added above is a non-governing
|
||||
predicate operand (and there is no GP), so update the gp_index value
|
||||
accordingly. */
|
||||
if (!instance.shape->has_gp_argument_p (instance))
|
||||
instance.gp_index = -1;
|
||||
}
|
||||
|
||||
/* Parse and move past an element type in FORMAT and return it as a type
|
||||
suffix. The format is:
|
||||
|
||||
|
|
@ -3301,6 +3317,14 @@ struct pmov_to_vector_lane_def : public overloaded_base<0>
|
|||
but it doesn't currently have the necessary information. */
|
||||
return c.require_immediate_range (1, 1, bytes - 1);
|
||||
}
|
||||
|
||||
/* This function has a predicate argument, and is a merging instruction, but
|
||||
the predicate is not a GP. */
|
||||
bool
|
||||
has_gp_argument_p (const function_instance &) const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
SHAPE (pmov_to_vector_lane)
|
||||
|
||||
|
|
|
|||
|
|
@ -3630,24 +3630,22 @@ gimple_folder::redirect_pred_x ()
|
|||
gimple *
|
||||
gimple_folder::fold_pfalse ()
|
||||
{
|
||||
if (pred == PRED_none)
|
||||
tree gp = gp_value (call);
|
||||
/* If there isn't a GP then we can't do any folding as the instruction isn't
|
||||
predicated. */
|
||||
if (!gp)
|
||||
return nullptr;
|
||||
tree arg0 = gimple_call_arg (call, 0);
|
||||
|
||||
if (pred == PRED_m)
|
||||
{
|
||||
/* Unary function shapes with _m predication are folded to the
|
||||
inactive vector (arg0), while other function shapes are folded
|
||||
to op1 (arg1). */
|
||||
tree arg1 = gimple_call_arg (call, 1);
|
||||
if (is_pfalse (arg1))
|
||||
return fold_call_to (arg0);
|
||||
if (is_pfalse (arg0))
|
||||
return fold_call_to (arg1);
|
||||
tree val = inactive_values (call);
|
||||
if (is_pfalse (gp))
|
||||
return fold_call_to (val);
|
||||
return nullptr;
|
||||
}
|
||||
if ((pred == PRED_x || pred == PRED_z) && is_pfalse (arg0))
|
||||
if ((pred == PRED_x || pred == PRED_z) && is_pfalse (gp))
|
||||
return fold_call_to (build_zero_cst (TREE_TYPE (lhs)));
|
||||
if (pred == PRED_implicit && is_pfalse (arg0))
|
||||
if (pred == PRED_implicit && is_pfalse (gp))
|
||||
{
|
||||
unsigned int flags = call_properties ();
|
||||
/* Folding to lhs = {0, ...} is not appropriate for intrinsics with
|
||||
|
|
|
|||
|
|
@ -402,6 +402,8 @@ public:
|
|||
bool could_trap_p () const;
|
||||
|
||||
vector_type_index gp_type_index () const;
|
||||
tree gp_value (gcall *) const;
|
||||
tree inactive_values (gcall *) const;
|
||||
tree gp_type () const;
|
||||
|
||||
unsigned int vectors_per_tuple () const;
|
||||
|
|
@ -435,6 +437,7 @@ public:
|
|||
group_suffix_index group_suffix_id;
|
||||
predication_index pred;
|
||||
fpm_mode_index fpm_mode;
|
||||
int gp_index;
|
||||
};
|
||||
|
||||
class registered_function;
|
||||
|
|
@ -800,6 +803,8 @@ public:
|
|||
virtual bool has_merge_argument_p (const function_instance &,
|
||||
unsigned int) const;
|
||||
|
||||
virtual bool has_gp_argument_p (const function_instance &) const;
|
||||
|
||||
virtual bool explicit_type_suffix_p (unsigned int) const = 0;
|
||||
|
||||
/* True if the group suffix is present in overloaded names.
|
||||
|
|
@ -948,6 +953,33 @@ function_instance::gp_type () const
|
|||
return acle_vector_types[0][gp_type_index ()];
|
||||
}
|
||||
|
||||
/* Return the tree value that should be used as the governing predicate of
|
||||
this function. If none then return NULL_TREE. */
|
||||
inline tree
|
||||
function_instance::gp_value (gcall *call) const
|
||||
{
|
||||
if (gp_index < 0)
|
||||
return NULL_TREE;
|
||||
|
||||
return gimple_call_arg (call, gp_index);
|
||||
}
|
||||
|
||||
/* Return the tree value that should be used for the inactive lanes should this
|
||||
function be a predicated function with a gp. Otherwise return NULL_TREE. */
|
||||
inline tree
|
||||
function_instance::inactive_values (gcall *call) const
|
||||
{
|
||||
if (gp_index < 0)
|
||||
return NULL_TREE;
|
||||
|
||||
/* Function is unary with m predicate. */
|
||||
if (gp_index == 1)
|
||||
return gimple_call_arg (call, 0);
|
||||
|
||||
/* Else the inactive values are the next element. */
|
||||
return gimple_call_arg (call, 1);
|
||||
}
|
||||
|
||||
/* If the function operates on tuples of vectors, return the number
|
||||
of vectors in the tuples, otherwise return 1. */
|
||||
inline unsigned int
|
||||
|
|
@ -1122,6 +1154,14 @@ function_shape::has_merge_argument_p (const function_instance &instance,
|
|||
return nargs == 1 && instance.pred == PRED_m;
|
||||
}
|
||||
|
||||
/* Return true if INSTANCE has an predicate argument that can be used as the global
|
||||
predicate. */
|
||||
inline bool
|
||||
function_shape::has_gp_argument_p (const function_instance &instance) const
|
||||
{
|
||||
return instance.pred != PRED_none;
|
||||
}
|
||||
|
||||
/* Return the mode of the result of a call. */
|
||||
inline machine_mode
|
||||
function_expander::result_mode () const
|
||||
|
|
|
|||
|
|
@ -3293,7 +3293,8 @@ avr_load_libgcc_p (rtx op)
|
|||
|
||||
return (n_bytes > 2
|
||||
&& !AVR_HAVE_LPMX
|
||||
&& avr_mem_flash_p (op));
|
||||
&& avr_mem_flash_p (op)
|
||||
&& MEM_ADDR_SPACE (op) == ADDR_SPACE_FLASH);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3645,6 +3646,46 @@ avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
|
|||
avr_asm_len ("sbiw %2,1", xop, plen, 1);
|
||||
|
||||
break; /* 2 */
|
||||
|
||||
/* cases 3 and 4 are only needed with ELPM but no ELPMx. */
|
||||
|
||||
case 3:
|
||||
if (REGNO (dest) == REG_Z - 2
|
||||
&& !reg_unused_after (insn, all_regs_rtx[REG_31]))
|
||||
avr_asm_len ("push r31", xop, plen, 1);
|
||||
|
||||
avr_asm_len ("%4lpm $ mov %A0,%3 $ adiw %2,1", xop, plen, 3);
|
||||
avr_asm_len ("%4lpm $ mov %B0,%3 $ adiw %2,1", xop, plen, 3);
|
||||
avr_asm_len ("%4lpm $ mov %C0,%3", xop, plen, 2);
|
||||
|
||||
if (REGNO (dest) == REG_Z - 2)
|
||||
{
|
||||
if (!reg_unused_after (insn, all_regs_rtx[REG_31]))
|
||||
avr_asm_len ("pop r31", xop, plen, 1);
|
||||
}
|
||||
else if (!reg_unused_after (insn, addr))
|
||||
avr_asm_len ("sbiw %2,2", xop, plen, 1);
|
||||
|
||||
break; /* 3 */
|
||||
|
||||
case 4:
|
||||
avr_asm_len ("%4lpm $ mov %A0,%3 $ adiw %2,1", xop, plen, 3);
|
||||
avr_asm_len ("%4lpm $ mov %B0,%3 $ adiw %2,1", xop, plen, 3);
|
||||
if (REGNO (dest) != REG_Z - 2)
|
||||
{
|
||||
avr_asm_len ("%4lpm $ mov %C0,%3 $ adiw %2,1", xop, plen, 3);
|
||||
avr_asm_len ("%4lpm $ mov %D0,%3", xop, plen, 2);
|
||||
if (!reg_unused_after (insn, addr))
|
||||
avr_asm_len ("sbiw %2,3", xop, plen, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
avr_asm_len ("%4lpm $ push %3 $ adiw %2,1", xop, plen, 3);
|
||||
avr_asm_len ("%4lpm $ mov %D0,%3", xop, plen, 2);
|
||||
avr_asm_len ("pop $C0", xop, plen, 1);
|
||||
}
|
||||
|
||||
break; /* 4 */
|
||||
}
|
||||
|
||||
break; /* REG */
|
||||
|
|
|
|||
|
|
@ -4091,9 +4091,17 @@
|
|||
(match_operand:PSI 2 "nonmemory_operand" "")))
|
||||
(clobber (reg:HI 26))
|
||||
(clobber (reg:DI 18))])]
|
||||
"AVR_HAVE_MUL"
|
||||
"AVR_HAVE_MUL
|
||||
|| (avropt_pr118012
|
||||
/* AVR_TINY passes args on the stack, so we cannot work
|
||||
around PR118012 like this. */
|
||||
&& ! AVR_TINY)"
|
||||
{
|
||||
if (s8_operand (operands[2], PSImode))
|
||||
if (!AVR_HAVE_MUL)
|
||||
{
|
||||
operands[2] = force_reg (PSImode, operands[2]);
|
||||
}
|
||||
else if (s8_operand (operands[2], PSImode))
|
||||
{
|
||||
rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
|
||||
emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
|
||||
|
|
@ -4198,7 +4206,9 @@
|
|||
(match_operand:PSI 2 "pseudo_register_or_const_int_operand" "rn")))
|
||||
(clobber (reg:HI 26))
|
||||
(clobber (reg:DI 18))]
|
||||
"AVR_HAVE_MUL && !reload_completed"
|
||||
"!reload_completed
|
||||
&& (AVR_HAVE_MUL
|
||||
|| (avropt_pr118012 && !AVR_TINY))"
|
||||
{ gcc_unreachable(); }
|
||||
"&& 1"
|
||||
[(set (reg:PSI 18)
|
||||
|
|
@ -4208,13 +4218,30 @@
|
|||
(parallel [(set (reg:PSI 22)
|
||||
(mult:PSI (reg:PSI 22)
|
||||
(reg:PSI 18)))
|
||||
(clobber (reg:QI 21))
|
||||
(clobber (reg:QI 25))
|
||||
(clobber (reg:HI 26))])
|
||||
(clobber (match_dup 3))
|
||||
(clobber (match_dup 4))
|
||||
(clobber (match_dup 5))])
|
||||
(set (match_dup 0)
|
||||
(reg:PSI 22))]
|
||||
{
|
||||
if (s8_operand (operands[2], PSImode))
|
||||
if (AVR_HAVE_MUL)
|
||||
{
|
||||
operands[3] = gen_rtx_REG (QImode, REG_21);
|
||||
operands[4] = gen_rtx_REG (QImode, REG_25);
|
||||
operands[5] = gen_rtx_REG (HImode, REG_26);
|
||||
}
|
||||
else
|
||||
{
|
||||
operands[3] = gen_rtx_REG (SImode, REG_18);
|
||||
operands[4] = gen_rtx_SCRATCH (QImode);
|
||||
operands[5] = gen_rtx_SCRATCH (HImode);
|
||||
}
|
||||
|
||||
if (!AVR_HAVE_MUL)
|
||||
{
|
||||
operands[2] = force_reg (PSImode, operands[2]);
|
||||
}
|
||||
else if (s8_operand (operands[2], PSImode))
|
||||
{
|
||||
rtx reg = force_reg (QImode, gen_int_mode (INTVAL (operands[2]), QImode));
|
||||
emit_insn (gen_mulsqipsi3 (operands[0], reg, operands[1]));
|
||||
|
|
@ -4273,6 +4300,37 @@
|
|||
"%~call __mulpsi3"
|
||||
[(set_attr "type" "xcall")])
|
||||
|
||||
(define_insn_and_split "*mulpsi3-nomul.libgcc_split"
|
||||
[(set (reg:PSI 22)
|
||||
(mult:PSI (reg:PSI 22)
|
||||
(reg:PSI 18)))
|
||||
(clobber (reg:SI 18))
|
||||
(clobber (scratch:QI))
|
||||
(clobber (scratch:HI))]
|
||||
"!AVR_HAVE_MUL && avropt_pr118012 && !AVR_TINY"
|
||||
"#"
|
||||
"&& reload_completed"
|
||||
[(parallel [(set (reg:PSI 22)
|
||||
(mult:PSI (reg:PSI 22)
|
||||
(reg:PSI 18)))
|
||||
(clobber (reg:SI 18))
|
||||
(clobber (scratch:QI))
|
||||
(clobber (scratch:HI))
|
||||
(clobber (reg:CC REG_CC))])])
|
||||
|
||||
(define_insn "*mulpsi3-nomul.libgcc"
|
||||
[(set (reg:PSI 22)
|
||||
(mult:PSI (reg:PSI 22)
|
||||
(reg:PSI 18)))
|
||||
(clobber (reg:SI 18))
|
||||
(clobber (scratch:QI))
|
||||
(clobber (scratch:HI))
|
||||
(clobber (reg:CC REG_CC))]
|
||||
"reload_completed
|
||||
&& !AVR_HAVE_MUL && avropt_pr118012 && !AVR_TINY"
|
||||
"%~call __mulpsi3"
|
||||
[(set_attr "type" "xcall")])
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; 24-bit signed/unsigned division and modulo.
|
||||
|
|
|
|||
|
|
@ -993,16 +993,6 @@
|
|||
[(set_attr "type" "simd_fmadd")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "fnma<mode>4"
|
||||
[(set (match_operand:FLASX 0 "register_operand" "=f")
|
||||
(fma:FLASX (neg:FLASX (match_operand:FLASX 1 "register_operand" "f"))
|
||||
(match_operand:FLASX 2 "register_operand" "f")
|
||||
(match_operand:FLASX 3 "register_operand" "0")))]
|
||||
"ISA_HAS_LASX"
|
||||
"xvfnmsub.<flasxfmt>\t%u0,%u1,%u2,%u0"
|
||||
[(set_attr "type" "simd_fmadd")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_expand "sqrt<mode>2"
|
||||
[(set (match_operand:FLASX 0 "register_operand")
|
||||
(sqrt:FLASX (match_operand:FLASX 1 "register_operand")))]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
/* 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),
|
||||
|
|
|
|||
|
|
@ -852,16 +852,6 @@
|
|||
[(set_attr "type" "simd_fmadd")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "fnma<mode>4"
|
||||
[(set (match_operand:FLSX 0 "register_operand" "=f")
|
||||
(fma:FLSX (neg:FLSX (match_operand:FLSX 1 "register_operand" "f"))
|
||||
(match_operand:FLSX 2 "register_operand" "f")
|
||||
(match_operand:FLSX 3 "register_operand" "0")))]
|
||||
"ISA_HAS_LSX"
|
||||
"vfnmsub.<flsxfmt>\t%w0,%w1,%w2,%w0"
|
||||
[(set_attr "type" "simd_fmadd")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_expand "sqrt<mode>2"
|
||||
[(set (match_operand:FLSX 0 "register_operand")
|
||||
(sqrt:FLSX (match_operand:FLSX 1 "register_operand")))]
|
||||
|
|
|
|||
|
|
@ -431,6 +431,17 @@
|
|||
[(set_attr "type" "simd_int_arith")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; <x>vfnmsub.{s/d}
|
||||
(define_insn "fnma<mode>4"
|
||||
[(set (match_operand:FVEC 0 "register_operand" "=f")
|
||||
(fma:FVEC (neg:FVEC (match_operand:FVEC 1 "register_operand" "f"))
|
||||
(match_operand:FVEC 2 "register_operand" "f")
|
||||
(match_operand:FVEC 3 "register_operand" "f")))]
|
||||
"!HONOR_SIGNED_ZEROS (<MODE>mode)"
|
||||
"<x>vfnmsub.<simdfmt>\t%<wu>0,%<wu>1,%<wu>2,%<wu>3"
|
||||
[(set_attr "type" "simd_fmadd")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
;; <x>vfcmp.*.{s/d} with defined RTX code
|
||||
;; There are no fcmp.{sugt/suge/cgt/cge}.{s/d} menmonics in GAS, so we have
|
||||
;; to reverse the operands ourselves :(.
|
||||
|
|
|
|||
|
|
@ -1792,12 +1792,13 @@ public:
|
|||
The fold routines expect the replacement statement to have the
|
||||
same lhs as the original call, so return the copy statement
|
||||
rather than the field update. */
|
||||
gassign *copy = gimple_build_assign (unshare_expr (f.lhs), rhs_tuple);
|
||||
gassign *copy = gimple_build_assign (f.lhs, rhs_tuple);
|
||||
|
||||
/* Get a reference to the individual vector. */
|
||||
tree field = tuple_type_field (TREE_TYPE (f.lhs));
|
||||
tree lhs_array
|
||||
= build3 (COMPONENT_REF, TREE_TYPE (field), f.lhs, field, NULL_TREE);
|
||||
= build3 (COMPONENT_REF, TREE_TYPE (field), unshare_expr (f.lhs),
|
||||
field, NULL_TREE);
|
||||
tree lhs_vector = build4 (ARRAY_REF, TREE_TYPE (rhs_vector), lhs_array,
|
||||
index, NULL_TREE, NULL_TREE);
|
||||
gassign *update = gimple_build_assign (lhs_vector, rhs_vector);
|
||||
|
|
|
|||
|
|
@ -11809,6 +11809,13 @@ riscv_dwarf_poly_indeterminate_value (unsigned int i, unsigned int *factor,
|
|||
*/
|
||||
gcc_assert (i == 1);
|
||||
*factor = BYTES_PER_RISCV_VECTOR.coeffs[1];
|
||||
|
||||
/* The factor will be zero if vector is not enabled. That ultimately
|
||||
causes problems in the dwarf2 emitter as the factor is used for
|
||||
a division, causing a divide by zero. */
|
||||
if (*factor == 0)
|
||||
*factor = 1;
|
||||
|
||||
*offset = 1;
|
||||
return RISCV_DWARF_VLENB;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,66 @@
|
|||
2025-11-04 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-04 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122253
|
||||
* decl2.cc (min_vis_expr_r): Don't mark no-linkage declarations
|
||||
as VISIBILITY_ANON.
|
||||
|
||||
2025-11-02 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-02 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122421
|
||||
* module.cc (trees_in::read_var_def): Don't handle class-scope
|
||||
variables anymore.
|
||||
(trees_in::read_class_def): Handle them here instead.
|
||||
|
||||
2025-11-01 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-01 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122381
|
||||
* module.cc (trees_out::core_vals): Write BASELINK_OPTYPE (aka
|
||||
TREE_CHAIN).
|
||||
(trees_in::core_vals): Read it.
|
||||
|
||||
2025-10-28 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-14 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
PR c++/122192
|
||||
* parser.cc (cp_parser_mem_initializer_id): Pass class_type
|
||||
instead of typename_type to cp_parser_class_name in the
|
||||
nested-name-specifier case.
|
||||
|
||||
2025-10-28 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-10 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
PR c++/122192
|
||||
* decl.cc (make_typename_type): Document base-specifier as
|
||||
another type-only lookup case.
|
||||
* parser.cc (cp_parser_class_name): Propagate tag_type to
|
||||
make_typename_type instead of hardcoding typename_type.
|
||||
(cp_parser_base_specifier): Pass class_type instead of
|
||||
typename_type as tag_type to cp_parser_class_name.
|
||||
|
||||
2025-10-28 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-27 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122310
|
||||
* module.cc (get_keyed_decl_scope): New function.
|
||||
(trees_out::get_merge_kind): Use it.
|
||||
(trees_out::key_mergeable): Use it.
|
||||
(maybe_key_decl): Key to the containing type for all members.
|
||||
|
||||
2025-10-14 Jason Merrill <jason@redhat.com>
|
||||
|
||||
Backported from master:
|
||||
|
|
|
|||
|
|
@ -4546,7 +4546,9 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
|
|||
- the tag corresponds to a class-key or 'enum' so
|
||||
[basic.lookup.elab] applies, or
|
||||
- the tag corresponds to scope_type or tf_qualifying_scope is
|
||||
set so [basic.lookup.qual]/1 applies.
|
||||
set so [basic.lookup.qual]/1 applies, or
|
||||
- we're inside a base-specifier so [class.derived.general]/2 applies;
|
||||
the tag will already be class_type in that case.
|
||||
TODO: If we'd set/track the scope_type tag thoroughly on all
|
||||
TYPENAME_TYPEs that are followed by :: then we wouldn't need the
|
||||
tf_qualifying_scope flag. */
|
||||
|
|
|
|||
|
|
@ -2867,7 +2867,12 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void *data)
|
|||
break;
|
||||
}
|
||||
addressable:
|
||||
if (! TREE_PUBLIC (t))
|
||||
if (decl_linkage (t) == lk_none)
|
||||
tpvis = type_visibility (TREE_TYPE (t));
|
||||
/* Decls that have had their visibility constrained will report
|
||||
as external linkage, but we still want to transitively constrain
|
||||
if we refer to them, so just check TREE_PUBLIC instead. */
|
||||
else if (!TREE_PUBLIC (t))
|
||||
tpvis = VISIBILITY_ANON;
|
||||
else
|
||||
tpvis = DECL_VISIBILITY (t);
|
||||
|
|
|
|||
|
|
@ -2789,6 +2789,8 @@ vec<tree, va_heap, vl_embed> *post_load_decls;
|
|||
typedef hash_map<tree, auto_vec<tree>> keyed_map_t;
|
||||
static keyed_map_t *keyed_table;
|
||||
|
||||
static tree get_keyed_decl_scope (tree);
|
||||
|
||||
/* Instantiations of temploid friends imported from another module
|
||||
need to be attached to the same module as the temploid. This maps
|
||||
these decls to the temploid they are instantiated from, as there is
|
||||
|
|
@ -6688,6 +6690,7 @@ trees_out::core_vals (tree t)
|
|||
WT (((lang_tree_node *)t)->baselink.binfo);
|
||||
WT (((lang_tree_node *)t)->baselink.functions);
|
||||
WT (((lang_tree_node *)t)->baselink.access_binfo);
|
||||
WT (((lang_tree_node *)t)->baselink.common.chain);
|
||||
break;
|
||||
|
||||
case CONSTRAINT_INFO:
|
||||
|
|
@ -7257,6 +7260,7 @@ trees_in::core_vals (tree t)
|
|||
RT (((lang_tree_node *)t)->baselink.binfo);
|
||||
RTU (((lang_tree_node *)t)->baselink.functions);
|
||||
RT (((lang_tree_node *)t)->baselink.access_binfo);
|
||||
RT (((lang_tree_node *)t)->baselink.common.chain);
|
||||
break;
|
||||
|
||||
case CONSTRAINT_INFO:
|
||||
|
|
@ -11275,19 +11279,11 @@ trees_out::get_merge_kind (tree decl, depset *dep)
|
|||
if (DECL_IMPLICIT_TYPEDEF_P (STRIP_TEMPLATE (decl))
|
||||
&& LAMBDA_TYPE_P (TREE_TYPE (decl)))
|
||||
{
|
||||
if (tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl)))
|
||||
{
|
||||
/* Lambdas attached to fields are keyed to its class. */
|
||||
if (TREE_CODE (scope) == FIELD_DECL)
|
||||
scope = TYPE_NAME (DECL_CONTEXT (scope));
|
||||
if (DECL_LANG_SPECIFIC (scope)
|
||||
&& DECL_MODULE_KEYED_DECLS_P (scope))
|
||||
{
|
||||
if (get_keyed_decl_scope (decl))
|
||||
mk = MK_keyed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Lambdas not attached to any mangling scope are TU-local. */
|
||||
else
|
||||
/* Lambdas not attached to any mangling scope are TU-local
|
||||
and so cannot be deduplicated. */
|
||||
mk = MK_unique;
|
||||
break;
|
||||
}
|
||||
|
|
@ -11589,16 +11585,9 @@ trees_out::key_mergeable (int tag, merge_kind mk, tree decl, tree inner,
|
|||
|
||||
case MK_keyed:
|
||||
{
|
||||
gcc_checking_assert (LAMBDA_TYPE_P (TREE_TYPE (inner)));
|
||||
tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (inner));
|
||||
gcc_checking_assert (TREE_CODE (scope) == VAR_DECL
|
||||
|| TREE_CODE (scope) == FIELD_DECL
|
||||
|| TREE_CODE (scope) == PARM_DECL
|
||||
|| TREE_CODE (scope) == TYPE_DECL
|
||||
|| TREE_CODE (scope) == CONCEPT_DECL);
|
||||
/* Lambdas attached to fields are keyed to the class. */
|
||||
if (TREE_CODE (scope) == FIELD_DECL)
|
||||
scope = TYPE_NAME (DECL_CONTEXT (scope));
|
||||
tree scope = get_keyed_decl_scope (inner);
|
||||
gcc_checking_assert (scope);
|
||||
|
||||
auto *root = keyed_table->get (scope);
|
||||
unsigned ix = root->length ();
|
||||
/* If we don't find it, we'll write a really big number
|
||||
|
|
@ -12859,12 +12848,11 @@ trees_in::read_var_def (tree decl, tree maybe_template)
|
|||
if (DECL_EXPLICIT_INSTANTIATION (decl)
|
||||
&& !DECL_EXTERNAL (decl))
|
||||
setup_explicit_instantiation_definition_linkage (decl);
|
||||
if (DECL_IMPLICIT_INSTANTIATION (decl)
|
||||
/* Class static data members are handled in read_class_def. */
|
||||
if (!DECL_CLASS_SCOPE_P (decl)
|
||||
&& (DECL_IMPLICIT_INSTANTIATION (decl)
|
||||
|| (DECL_EXPLICIT_INSTANTIATION (decl)
|
||||
&& !DECL_EXTERNAL (decl))
|
||||
|| (DECL_CLASS_SCOPE_P (decl)
|
||||
&& !DECL_VTABLE_OR_VTT_P (decl)
|
||||
&& !DECL_TEMPLATE_INFO (decl)))
|
||||
&& !DECL_EXTERNAL (decl))))
|
||||
note_vague_linkage_variable (decl);
|
||||
}
|
||||
if (!dyn_init)
|
||||
|
|
@ -13278,6 +13266,10 @@ trees_in::read_class_def (tree defn, tree maybe_template)
|
|||
DECL_ACCESS (d) = tree_cons (type, access, list);
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (decl) == VAR_DECL
|
||||
&& TREE_CODE (maybe_template) != TEMPLATE_DECL)
|
||||
note_vague_linkage_variable (decl);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -20916,9 +20908,21 @@ maybe_key_decl (tree ctx, tree decl)
|
|||
&& TREE_CODE (ctx) != CONCEPT_DECL)
|
||||
return;
|
||||
|
||||
/* For fields, key it to the containing type to handle deduplication
|
||||
correctly. */
|
||||
if (TREE_CODE (ctx) == FIELD_DECL)
|
||||
/* For members, key it to the containing type to handle deduplication
|
||||
correctly. For fields, this is necessary as FIELD_DECLs have no
|
||||
dep and so would only be streamed after the lambda type, defeating
|
||||
our ability to merge them.
|
||||
|
||||
Other class-scope key decls might depend on the type of the lambda
|
||||
but be within the same cluster; we need to ensure that we never
|
||||
first see the key decl while streaming the lambda type as merging
|
||||
would then fail when comparing the partially-streamed lambda type
|
||||
of the key decl with the existing (PR c++/122310).
|
||||
|
||||
Perhaps sort_cluster can be adjusted to handle this better, but
|
||||
this is a simple workaround (and might down on the number of
|
||||
entries in keyed_table as a bonus). */
|
||||
while (DECL_CLASS_SCOPE_P (ctx))
|
||||
ctx = TYPE_NAME (DECL_CONTEXT (ctx));
|
||||
|
||||
if (!keyed_table)
|
||||
|
|
@ -20933,6 +20937,30 @@ maybe_key_decl (tree ctx, tree decl)
|
|||
vec.safe_push (decl);
|
||||
}
|
||||
|
||||
/* Find the scope that the lambda DECL is keyed to, if any. */
|
||||
|
||||
static tree
|
||||
get_keyed_decl_scope (tree decl)
|
||||
{
|
||||
gcc_checking_assert (LAMBDA_TYPE_P (TREE_TYPE (decl)));
|
||||
tree scope = LAMBDA_TYPE_EXTRA_SCOPE (TREE_TYPE (decl));
|
||||
if (!scope)
|
||||
return NULL_TREE;
|
||||
|
||||
gcc_checking_assert (TREE_CODE (scope) == VAR_DECL
|
||||
|| TREE_CODE (scope) == FIELD_DECL
|
||||
|| TREE_CODE (scope) == PARM_DECL
|
||||
|| TREE_CODE (scope) == TYPE_DECL
|
||||
|| TREE_CODE (scope) == CONCEPT_DECL);
|
||||
|
||||
while (DECL_CLASS_SCOPE_P (scope))
|
||||
scope = TYPE_NAME (DECL_CONTEXT (scope));
|
||||
|
||||
gcc_checking_assert (DECL_LANG_SPECIFIC (scope)
|
||||
&& DECL_MODULE_KEYED_DECLS_P (scope));
|
||||
return scope;
|
||||
}
|
||||
|
||||
/* DECL is an instantiated friend that should be attached to the same
|
||||
module that ORIG is. */
|
||||
|
||||
|
|
|
|||
|
|
@ -18509,7 +18509,7 @@ cp_parser_mem_initializer_id (cp_parser* parser)
|
|||
return cp_parser_class_name (parser,
|
||||
/*typename_keyword_p=*/true,
|
||||
/*template_keyword_p=*/template_p,
|
||||
typename_type,
|
||||
class_type,
|
||||
/*check_dependency_p=*/true,
|
||||
/*class_head_p=*/false,
|
||||
/*is_declaration=*/true);
|
||||
|
|
@ -27809,8 +27809,7 @@ cp_parser_class_name (cp_parser *parser,
|
|||
/* If this is a typename, create a TYPENAME_TYPE. */
|
||||
if (typename_p && decl != error_mark_node)
|
||||
{
|
||||
decl = make_typename_type (scope, decl, typename_type,
|
||||
/*complain=*/tf_error);
|
||||
decl = make_typename_type (scope, decl, tag_type, /*complain=*/tf_error);
|
||||
if (decl != error_mark_node)
|
||||
decl = TYPE_NAME (decl);
|
||||
}
|
||||
|
|
@ -30203,7 +30202,7 @@ cp_parser_base_specifier (cp_parser* parser)
|
|||
type = cp_parser_class_name (parser,
|
||||
class_scope_p,
|
||||
template_p,
|
||||
typename_type,
|
||||
class_type,
|
||||
/*check_dependency_p=*/true,
|
||||
/*class_head_p=*/false,
|
||||
/*is_declaration=*/true);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,26 @@
|
|||
2025-11-01 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
Backported from master:
|
||||
2025-10-25 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
PR fortran/114023
|
||||
* trans-expr.cc (gfc_trans_pointer_assignment): Always set dtype
|
||||
when remapping a pointer. For unlimited polymorphic LHS use
|
||||
elem_len from RHS.
|
||||
* trans-intrinsic.cc (gfc_conv_is_contiguous_expr): Extend inline
|
||||
generated code for IS_CONTIGUOUS for pointer arguments to detect
|
||||
when span differs from the element size.
|
||||
|
||||
2025-11-01 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
Backported from master:
|
||||
2025-10-24 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
PR fortran/122386
|
||||
* dependency.cc (gfc_ref_needs_temporary_p): Revert r16-518.
|
||||
* trans-intrinsic.cc (gfc_conv_intrinsic_transfer): Force temporary
|
||||
for SOURCE not being a simply-contiguous array.
|
||||
|
||||
2025-10-25 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
Backported from master:
|
||||
|
|
|
|||
|
|
@ -944,12 +944,8 @@ gfc_ref_needs_temporary_p (gfc_ref *ref)
|
|||
types), not in characters. */
|
||||
return subarray_p;
|
||||
|
||||
case REF_INQUIRY:
|
||||
/* Within an array reference, inquiry references of complex
|
||||
variables generally need a temporary. */
|
||||
return subarray_p;
|
||||
|
||||
case REF_COMPONENT:
|
||||
case REF_INQUIRY:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11232,21 +11232,33 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
|
|||
int dim;
|
||||
gcc_assert (remap->u.ar.dimen == expr1->rank);
|
||||
|
||||
/* Always set dtype. */
|
||||
tree dtype = gfc_conv_descriptor_dtype (desc);
|
||||
tmp = gfc_get_dtype (TREE_TYPE (desc));
|
||||
gfc_add_modify (&block, dtype, tmp);
|
||||
|
||||
/* For unlimited polymorphic LHS use elem_len from RHS. */
|
||||
if (UNLIMITED_POLY (expr1) && expr2->ts.type != BT_CLASS)
|
||||
{
|
||||
tree elem_len;
|
||||
tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&expr2->ts));
|
||||
elem_len = fold_convert (gfc_array_index_type, tmp);
|
||||
elem_len = gfc_evaluate_now (elem_len, &block);
|
||||
tmp = gfc_conv_descriptor_elem_len (desc);
|
||||
gfc_add_modify (&block, tmp,
|
||||
fold_convert (TREE_TYPE (tmp), elem_len));
|
||||
}
|
||||
|
||||
if (rank_remap)
|
||||
{
|
||||
/* Do rank remapping. We already have the RHS's descriptor
|
||||
converted in rse and now have to build the correct LHS
|
||||
descriptor for it. */
|
||||
|
||||
tree dtype, data, span;
|
||||
tree data, span;
|
||||
tree offs, stride;
|
||||
tree lbound, ubound;
|
||||
|
||||
/* Set dtype. */
|
||||
dtype = gfc_conv_descriptor_dtype (desc);
|
||||
tmp = gfc_get_dtype (TREE_TYPE (desc));
|
||||
gfc_add_modify (&block, dtype, tmp);
|
||||
|
||||
/* Copy data pointer. */
|
||||
data = gfc_conv_descriptor_data_get (rse.expr);
|
||||
gfc_conv_descriptor_data_set (&block, desc, data);
|
||||
|
|
|
|||
|
|
@ -2315,10 +2315,14 @@ gfc_conv_is_contiguous_expr (gfc_se *se, gfc_expr *arg)
|
|||
int i;
|
||||
tree fncall0;
|
||||
gfc_array_spec *as;
|
||||
gfc_symbol *sym = NULL;
|
||||
|
||||
if (arg->ts.type == BT_CLASS)
|
||||
gfc_add_class_array_ref (arg);
|
||||
|
||||
if (arg->expr_type == EXPR_VARIABLE)
|
||||
sym = arg->symtree->n.sym;
|
||||
|
||||
ss = gfc_walk_expr (arg);
|
||||
gcc_assert (ss != gfc_ss_terminator);
|
||||
gfc_init_se (&argse, NULL);
|
||||
|
|
@ -2341,7 +2345,7 @@ gfc_conv_is_contiguous_expr (gfc_se *se, gfc_expr *arg)
|
|||
fncall0 = build_call_expr_loc (input_location,
|
||||
gfor_fndecl_is_contiguous0, 1, desc);
|
||||
se->expr = fncall0;
|
||||
se->expr = convert (logical_type_node, se->expr);
|
||||
se->expr = convert (boolean_type_node, se->expr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2373,6 +2377,22 @@ gfc_conv_is_contiguous_expr (gfc_se *se, gfc_expr *arg)
|
|||
}
|
||||
se->expr = cond;
|
||||
}
|
||||
|
||||
/* A pointer that does not have the CONTIGUOUS attribute needs to be checked
|
||||
if it points to an array whose span differs from the element size. */
|
||||
if (as && sym && IS_POINTER(sym) && !sym->attr.contiguous)
|
||||
{
|
||||
tree span = gfc_conv_descriptor_span_get (desc);
|
||||
tmp = fold_convert (TREE_TYPE (span),
|
||||
gfc_conv_descriptor_elem_len (desc));
|
||||
cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
|
||||
span, tmp);
|
||||
se->expr = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
|
||||
boolean_type_node, cond,
|
||||
convert (boolean_type_node, se->expr));
|
||||
}
|
||||
|
||||
gfc_free_ss_chain (ss);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -8541,13 +8561,18 @@ gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
|
|||
}
|
||||
else
|
||||
{
|
||||
bool simply_contiguous = gfc_is_simply_contiguous (arg->expr,
|
||||
false, true);
|
||||
argse.want_pointer = 0;
|
||||
/* A non-contiguous SOURCE needs packing. */
|
||||
if (!simply_contiguous)
|
||||
argse.force_tmp = 1;
|
||||
gfc_conv_expr_descriptor (&argse, arg->expr);
|
||||
source = gfc_conv_descriptor_data_get (argse.expr);
|
||||
source_type = gfc_get_element_type (TREE_TYPE (argse.expr));
|
||||
|
||||
/* Repack the source if not simply contiguous. */
|
||||
if (!gfc_is_simply_contiguous (arg->expr, false, true))
|
||||
if (!simply_contiguous)
|
||||
{
|
||||
tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);
|
||||
|
||||
|
|
|
|||
|
|
@ -522,6 +522,11 @@ update_equiv (int regno)
|
|||
{
|
||||
rtx x;
|
||||
|
||||
/* If REGNO is beyond the length of the equivalence array structure,
|
||||
then there's nothing to update. */
|
||||
if (regno >= ira_reg_equiv_len)
|
||||
return;
|
||||
|
||||
if ((x = ira_reg_equiv[regno].memory) != NULL_RTX)
|
||||
ira_reg_equiv[regno].memory
|
||||
= simplify_replace_fn_rtx (x, NULL_RTX, loc_equivalence_callback,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,145 @@
|
|||
2025-11-04 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-04 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122253
|
||||
* g++.dg/modules/internal-16.C: New test.
|
||||
|
||||
2025-11-03 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-01 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
PR rtl-optimization/122321
|
||||
* gcc.target/riscv/rvv/autovec/pr122321.c: New test.
|
||||
|
||||
2025-11-03 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-26 Andrew Pinski <andrew.pinski@oss.qualcomm.com>
|
||||
|
||||
PR target/122270
|
||||
* gcc.target/riscv/rvv/base/pr122270-1.c: New test.
|
||||
|
||||
2025-11-02 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-02 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122421
|
||||
* g++.dg/modules/inst-6_a.C: New test.
|
||||
* g++.dg/modules/inst-6_b.C: New test.
|
||||
|
||||
2025-11-01 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
Backported from master:
|
||||
2025-10-25 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
PR fortran/114023
|
||||
* gfortran.dg/is_contiguous_5.f90: New test.
|
||||
|
||||
2025-11-01 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
Backported from master:
|
||||
2025-10-24 Harald Anlauf <anlauf@gmx.de>
|
||||
|
||||
PR fortran/122386
|
||||
* gfortran.dg/transfer_array_subref_2.f90: New test.
|
||||
|
||||
2025-11-01 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-11-01 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122381
|
||||
* g++.dg/modules/convop-2_a.H: New test.
|
||||
* g++.dg/modules/convop-2_b.C: New test.
|
||||
|
||||
2025-10-31 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-27 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
PR tree-optimization/122408
|
||||
* gfortran.target/aarch64/pr122408_1.f90: New test.
|
||||
* gfortran.target/aarch64/pr122408_2.f90: New test.
|
||||
|
||||
2025-10-31 Jinyang He <hejinyang@loongson.cn>
|
||||
|
||||
Backported from master:
|
||||
2025-10-30 Jinyang He <hejinyang@loongson.cn>
|
||||
Peng Fan <fanpeng@loongson.cn>
|
||||
|
||||
* 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.
|
||||
|
||||
2025-10-30 Guo Jie <guojie@loongson.cn>
|
||||
|
||||
Backported from master:
|
||||
2025-10-30 Guo Jie <guojie@loongson.cn>
|
||||
|
||||
* gcc.target/loongarch/fnmam4-vec.c: New test.
|
||||
|
||||
2025-10-28 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-14 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
PR c++/122192
|
||||
* g++.dg/template/dependent-base6.C: Verify mem-initializer-id
|
||||
qualified name lookup is type-only too.
|
||||
|
||||
2025-10-28 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-10 Patrick Palka <ppalka@redhat.com>
|
||||
|
||||
PR c++/122192
|
||||
* g++.dg/template/dependent-base6.C: New test.
|
||||
|
||||
2025-10-28 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-27 Nathaniel Shead <nathanieloshead@gmail.com>
|
||||
|
||||
PR c++/122310
|
||||
* g++.dg/modules/lambda-12.h: New test.
|
||||
* g++.dg/modules/lambda-12_a.H: New test.
|
||||
* g++.dg/modules/lambda-12_b.C: New test.
|
||||
|
||||
2025-10-27 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/122394
|
||||
* g++.dg/opt/pr122394.C: New test.
|
||||
|
||||
2025-10-27 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-13 Jeff Law <jlaw@ventanamicro.com>
|
||||
|
||||
PR target/120674
|
||||
* gcc.target/riscv/pr120674.c: New test.
|
||||
|
||||
2025-10-27 Tamar Christina <tamar.christina@arm.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-17 Tamar Christina <tamar.christina@arm.com>
|
||||
Jennifer Schmitz <jschmitz@nvidia.com>
|
||||
|
||||
PR target/121604
|
||||
* gcc.target/aarch64/sve/pr121604_brk.c: New test.
|
||||
* gcc.target/aarch64/sve2/pr121604_pmov.c: New test.
|
||||
|
||||
2025-10-27 H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
Backported from master:
|
||||
2025-10-27 H.J. Lu <hjl.tools@gmail.com>
|
||||
|
||||
PR target/122323
|
||||
* gcc.target/i386/builtin-copysign-8b.c: Add -mtune=generic.
|
||||
|
||||
2025-10-26 Alexandre Oliva <oliva@adacore.com>
|
||||
|
||||
Backported from master:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
// PR c++/122381
|
||||
// { dg-additional-options "-fmodule-header" }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
template <typename T> struct color_ref {
|
||||
operator int() const { return 0; }
|
||||
int foo(color_ref x) {
|
||||
return x.operator int();
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// PR c++/122381
|
||||
// { dg-additional-options "-fmodules" }
|
||||
|
||||
import "convop-2_a.H";
|
||||
template struct color_ref<int>;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// PR c++/122421
|
||||
// { dg-additional-options "-fmodules" }
|
||||
// { dg-module-cmi M }
|
||||
|
||||
export module M;
|
||||
|
||||
export template <typename T> struct Type {
|
||||
static const int arr[3];
|
||||
};
|
||||
|
||||
extern template const int Type<double>::arr[3];
|
||||
template <typename T> const int Type<T>::arr[] = { 42, 43, 44 };
|
||||
|
||||
export Type<int> ti;
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
// PR c++/122421
|
||||
// { dg-additional-options "-fmodules" }
|
||||
|
||||
import M;
|
||||
|
||||
int main() {
|
||||
const int& a = Type<int>::arr[0];
|
||||
const int& b = Type<double>::arr[0];
|
||||
}
|
||||
|
||||
// { dg-final { scan-assembler {_ZNW1M4TypeIiE3arrE:} } }
|
||||
// { dg-final { scan-assembler-not {_ZNW1M4TypeIdE3arrE:} } }
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// PR c++/122253
|
||||
// { dg-additional-options "-fmodules -Wtemplate-names-tu-local" }
|
||||
|
||||
export module M;
|
||||
|
||||
template <int> struct ic {};
|
||||
struct S {
|
||||
constexpr operator int() const { return 5; }
|
||||
constexpr int operator&() const { return 8; }
|
||||
};
|
||||
|
||||
template <typename T> inline void a(T) {
|
||||
T a;
|
||||
static T b;
|
||||
ic<a>{};
|
||||
ic<b>{};
|
||||
ic<&a>{};
|
||||
ic<&b>{};
|
||||
}
|
||||
|
||||
template <typename T> inline auto b(T x) {
|
||||
return [&](auto y) {
|
||||
return [=](auto z) {
|
||||
return ic<(int)x + (int)&y + (int)z>{};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template void a(S);
|
||||
ic<5 + 8 + 5> x = b(S{})(S{})(S{});
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// PR c++/122310
|
||||
struct Foo {
|
||||
constexpr static inline auto do_nothing = [](auto && ...){};
|
||||
using TNothing = decltype(do_nothing);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct X {
|
||||
struct Inner {
|
||||
union MoreInner {
|
||||
static constexpr auto x = []{};
|
||||
#if __cplusplus >= 202002L
|
||||
static decltype([]{}) y;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
using A = decltype(Inner::MoreInner::x);
|
||||
#if __cplusplus >= 202002L
|
||||
using B = decltype(Inner::MoreInner::y);
|
||||
#endif
|
||||
};
|
||||
|
||||
inline X<int>::A* a{};
|
||||
#if __cplusplus >= 202002L
|
||||
inline X<int>::B* b{};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// PR c++/122310
|
||||
// { dg-additional-options "-fmodule-header" }
|
||||
// { dg-module-cmi {} }
|
||||
|
||||
#include "lambda-12.h"
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// PR c++/122310
|
||||
// { dg-additional-options "-fmodules -fno-module-lazy" }
|
||||
|
||||
#include "lambda-12.h"
|
||||
import "lambda-12_a.H";
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
// PR tree-optimization/122394
|
||||
// { dg-do compile { target c++23 } }
|
||||
// { dg-options "-O1 -g" }
|
||||
|
||||
#include <compare>
|
||||
|
||||
struct A {
|
||||
friend auto operator<=> (A, A) = default;
|
||||
double a;
|
||||
};
|
||||
void foo ();
|
||||
A b, c;
|
||||
|
||||
void
|
||||
bar ()
|
||||
{
|
||||
bool d = c >= b;
|
||||
if (d)
|
||||
foo ();
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
// PR c++/122192
|
||||
// Verify name lookup within a base-specifier is type-only.
|
||||
|
||||
struct A {
|
||||
int B;
|
||||
struct B { };
|
||||
};
|
||||
|
||||
struct S1 : A::B { }; // OK
|
||||
|
||||
template<class T> struct S2 : T::B { // OK, used to fail
|
||||
S2() : T::B() { } // Also OK
|
||||
};
|
||||
template struct S2<A>;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
/* { dg-final { check-function-bodies "**" "" "" } } */
|
||||
|
||||
#include <arm_sve.h>
|
||||
|
||||
/*
|
||||
** foo:
|
||||
** ptrue p0\.b, all
|
||||
** brkb p0\.b, p0/z, p0\.b
|
||||
** ret
|
||||
*/
|
||||
svbool_t foo () {
|
||||
return svbrkb_b_m (svpfalse (), svptrue_b8 (), svptrue_b8 ());
|
||||
}
|
||||
|
||||
/*
|
||||
** bar:
|
||||
** ptrue p0\.b, all
|
||||
** brka p0\.b, p0/z, p0\.b
|
||||
** ret
|
||||
*/
|
||||
svbool_t bar () {
|
||||
return svbrka_b_m (svpfalse (), svptrue_b8 (), svptrue_b8 ());
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -march=armv8.2-a+sve2p1" } */
|
||||
/* { dg-final { check-function-bodies "**" "" "" } } */
|
||||
|
||||
#include <arm_sve.h>
|
||||
|
||||
/*
|
||||
** f:
|
||||
** pfalse p([0-7]+)\.b
|
||||
** mov z0\.b, #-1
|
||||
** pmov z0\[1\], p\1\.d
|
||||
** ret
|
||||
*/
|
||||
svuint64_t f () {
|
||||
return svpmov_lane_u64_m (svdup_u64 (~0UL), svpfalse (), 1);
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -mno-avx512f -mavx" } */
|
||||
/* { dg-options "-O2 -mno-avx512f -mavx -mtune=generic" } */
|
||||
/* Keep labels and directives ('.cfi_startproc', '.cfi_endproc'). */
|
||||
/* { dg-final { check-function-bodies "**" "" "" { target { ! ia32 } } {^\t?\.} } } */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ void
|
|||
test_lez ()
|
||||
{
|
||||
if (lm <= 0)
|
||||
lr &= (1 << 16);
|
||||
lr |= (1 << 16);
|
||||
lr += lm;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-Ofast -mlasx -ftree-vectorize" } */
|
||||
/* { dg-require-effective-target loongarch_asx } */
|
||||
|
||||
void
|
||||
foo (float *u, float x, float *y, float z)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 1024; i++)
|
||||
*(u++) = (x - y[i] * z);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "\tvori.b"} } */
|
||||
/* { dg-final { scan-assembler-not "\txvori.b"} } */
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-additional-options "-g -w -march=rv32gcv -mabi=ilp32" { target rv32 } } */
|
||||
/* { dg-additional-options "-g -w -march=rv64gcv -mabi=lp64d" { target rv64 } } */
|
||||
|
||||
#pragma riscv intrinsic "vector"
|
||||
void GB_AxB_saxpy5_unrolled_rvv() { vfloat64m8_t vc; }
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-march=rv64gcv -mabi=lp64d -w -O0" { target rv64 } } */
|
||||
/* { dg-options "-march=rv32gcv -mabi=ilp32 -w -O0" { target rv32 } } */
|
||||
|
||||
|
||||
typedef int a;
|
||||
typedef signed char b;
|
||||
typedef char c;
|
||||
typedef short d;
|
||||
typedef unsigned short e;
|
||||
typedef a f;
|
||||
typedef unsigned g;
|
||||
typedef long h;
|
||||
h j, k, l, m, n, o;
|
||||
int p, q, r, s;
|
||||
short t;
|
||||
volatile a u;
|
||||
a v[];
|
||||
char w, x;
|
||||
a *y, *z;
|
||||
a **aa;
|
||||
__attribute__((always_inline)) b __attribute__((vector_size(16)))
|
||||
ab(f __attribute__((vector_size(8 * sizeof(f)))), d ac,
|
||||
d __attribute__((vector_size(2 * sizeof(d)))), d) {
|
||||
return __builtin_shufflevector(
|
||||
(b __attribute__((vector_size(16)))) __builtin_convertvector(
|
||||
(d __attribute__((vector_size(16 *sizeof(d))))){
|
||||
ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
|
||||
c __attribute__((vector_size(16)))) |
|
||||
__builtin_convertvector(
|
||||
(d __attribute__((vector_size(16 *sizeof(d))))){
|
||||
ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
|
||||
c __attribute__((vector_size(16)))),
|
||||
__builtin_convertvector(
|
||||
(d __attribute__((vector_size(16 *sizeof(d))))){
|
||||
ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac, ac},
|
||||
b __attribute__((vector_size(16)))),
|
||||
3, 21, 0, 2, 2, 7, 1, 8, 4, 0, 8, 0, 8, 9, 5, 6);
|
||||
}
|
||||
__attribute__((always_inline)) g
|
||||
ad(d ae, h __attribute__((vector_size(32 * sizeof(h))))) {
|
||||
g f = 6318;
|
||||
return (8 ? ae / 786856318u : 0) & ae;
|
||||
}
|
||||
a(af)(a, int);
|
||||
void(ag)(long);
|
||||
char(ah)(char, char);
|
||||
char(ai)(char);
|
||||
short(aj)(short, short);
|
||||
int ak(long, int *, int *, char, int);
|
||||
void al(signed, a *, int *, long);
|
||||
char am(int *, short, short);
|
||||
void an(int *, long, int);
|
||||
void ao(int, int *, a *);
|
||||
a ap() {
|
||||
int *aq, *ar, *as;
|
||||
short at;
|
||||
char au, av, aw = 2;
|
||||
long ax, ay, az = j;
|
||||
int ba, i;
|
||||
g __attribute__((vector_size(16 * sizeof(g)))) bb = {80};
|
||||
b __attribute__((vector_size(4))) bc = {6};
|
||||
int bd[1];
|
||||
char *be = &w;
|
||||
int bf, bg = q;
|
||||
a **bh[] = {
|
||||
&y, &z, &z, &y, &y, &y, &y, &y, &z, &z, &y, &z, &y, &y, &y, &y, &z, &y,
|
||||
&z, &y, &y, &y, &z, &z, &z, &y, &z, &z, &z, &y, &z, &z, &y, &z, &z, &y,
|
||||
&z, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y, &y, 0, &z, 0,
|
||||
&z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z, &y, &z, &z, &y,
|
||||
0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y, &y, 0,
|
||||
&z, 0, &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z, &y, &z,
|
||||
&z, &y, 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z, &z, &y,
|
||||
&y, 0, &z, 0, &z, 0, &y, &z, &z, 0, &z, 0, &z, &z, &z, &y, &z, &z,
|
||||
&y, &z, &z, &y, 0, &z, 0, &z, &z, &y, 0, &z, 0, &y, 0, &y, &y, &z,
|
||||
&z, &y, &y, 0, &z, 0, &z, 0, &y, &z, &z, 0, 0, &z, 0, &z, &z, &z,
|
||||
&y, &z, &z, &y, &z, &z, &y, 0, &z, 0, 0, &z, &z};
|
||||
for (; i; i++)
|
||||
bd[i] = p;
|
||||
h __attribute__((vector_size(32 * sizeof(h))))
|
||||
bi = {2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681,
|
||||
2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681,
|
||||
2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681, 2681},
|
||||
bj = __builtin_convertvector(
|
||||
(c __attribute__((vector_size(32)))){
|
||||
aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw,
|
||||
aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw, aw},
|
||||
h __attribute__((vector_size(32 * sizeof(h))))),
|
||||
bk = __builtin_convertvector(
|
||||
__builtin_shufflevector(bb, bb, 4, 8, 7, 9, 1, 10, 4, 7, 0, 4, 3, 5, 6, 7,
|
||||
6, 2, 2, 20, 6, 4, 7, 7, 9, 7, 4, 9, 8, 6, 1, 0,
|
||||
6, 9),
|
||||
h __attribute__((vector_size(32 * sizeof(h)))));
|
||||
bb = __builtin_convertvector(
|
||||
ab(__builtin_shufflevector(
|
||||
__builtin_shufflevector(
|
||||
__builtin_convertvector(
|
||||
__builtin_shufflevector(bb, bb, 1, 31, 8, 2, 3, 7, 4, 0, 7,
|
||||
3, 4, 6, 7, 1, 9, 3, 8, 7, 1, 8, 5,
|
||||
3, 9, 9, 0, 3, 2, 8, 5, 2, 5, 3),
|
||||
f __attribute__((vector_size(32 * sizeof(f))))),
|
||||
(f __attribute__((vector_size(32 * sizeof(f))))){
|
||||
800761418310502961587690471176286910032020044212442466872080013589354162852207417903424527024812447907811618435019152886919380169872910001752451018659493155196043018716516518746289614523948734758456011127254301274351182132760058399143431214610613191313926994549901191890929084305862034120561651877003645},
|
||||
32, 44),
|
||||
(f __attribute__((vector_size(2 * sizeof(f))))){o}, 1, 0, 3, 0, 2,
|
||||
1, 3, 3),
|
||||
ad(__builtin_clzg((g)aw, (f)bb[9]),
|
||||
(h __attribute__((vector_size(32 * sizeof(h))))){
|
||||
bi[0] ?: bk[0], bi[1] ? 1 : bk[1], bi[2] ? 2 : bk[2],
|
||||
bi[3] ? 3 : bk[3], bi[4] ? 4 : bk[4], bi[5] ? 5 : bk[5],
|
||||
bi[6] ? 6 : bk[6], bi[7] ? 7 : bk[7], bi[8] ? 8 : bk[8],
|
||||
bi[9] ? 9 : bk[9], bi[0] ? 10 : bk[0], bi[1] ? 1 : bk[1],
|
||||
bi[2] ? 2 : bk[2], bi[3] ? 3 : bk[3], bi[4] ? 4 : bk[4],
|
||||
bi[5] ? 5 : bk[5], bi[6] ? 6 : bk[6], bi[7] ? 7 : bk[7],
|
||||
bi[8] ? 8 : bk[8], bi[9] ? 9 : bk[9], bi[0] ? 20 : bk[0],
|
||||
bi[1] ? 1 : bk[1], bi[2] ? 2 : bk[2], bi[3] ? 3 : bk[3],
|
||||
bi[4] ? bj[4] : 4, bi[5] ?: 5, bi[6] ?: 6,
|
||||
bi[7] ? 0 : 7, bi[8] ?: 8, bi[9] ? 0 : 9,
|
||||
bi[0] ? 0 : 30, bi[1] ?: 1}),
|
||||
(d __attribute__((vector_size(2 * sizeof(d)))))
|
||||
__builtin_shufflevector(
|
||||
__builtin_convertvector(
|
||||
__builtin_shufflevector(bb, bb, 2, 7, 21, 6),
|
||||
e __attribute__((vector_size(4 * sizeof(e))))),
|
||||
__builtin_convertvector(
|
||||
(c __attribute__((vector_size(4)))){aw, aw},
|
||||
e __attribute__((vector_size(4 * sizeof(e))))),
|
||||
5, 1) +
|
||||
(__builtin_convertvector(
|
||||
__builtin_shufflevector(bb, bb, 4, 5),
|
||||
e __attribute__((vector_size(2 * sizeof(e))))) <=
|
||||
__builtin_convertvector(
|
||||
(c __attribute__((vector_size(2)))){aw},
|
||||
e __attribute__((vector_size(2 * sizeof(e)))))),
|
||||
n ? bb[5] << n : aw),
|
||||
g __attribute__((vector_size(16 * sizeof(g)))));
|
||||
ag(aw & t);
|
||||
at = aj(aw, v[1]);
|
||||
au = ah(at, aw);
|
||||
ba = af((1 == ax != aw) <= aw <= au, aw);
|
||||
ao(0, &bd[0], &r);
|
||||
o = ay;
|
||||
an(aq, aw, k);
|
||||
av = am(ar, l, k);
|
||||
*be = ai(*be);
|
||||
al(x, as, &bd[0], aw);
|
||||
bg = ak(u, &s, &bf, aw, aw);
|
||||
as = *aa;
|
||||
return m;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/* { dg-options "" } */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-add-options riscv_v } */
|
||||
/* PR target/122270 */
|
||||
|
||||
#include "riscv_vector.h"
|
||||
|
||||
void a(vfloat32m1_t b, vfloat32m1x4_t *c) {
|
||||
*c = __riscv_vset_v_f32m1_f32m1x4(*c, 3, b);
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
! { dg-do run }
|
||||
! PR fortran/114023 - IS_CONTIGUOUS and pointers to non-contiguous targets
|
||||
!
|
||||
! Based on testcase by Federico Perini
|
||||
|
||||
program main
|
||||
implicit none
|
||||
complex, parameter :: cvals(*) = [(1,-1),(2,-2),(3,-3)]
|
||||
complex , target :: cref(size(cvals)) = cvals ! Reference
|
||||
complex, allocatable, target :: carr(:) ! Test
|
||||
|
||||
type cx
|
||||
real :: re, im
|
||||
end type cx
|
||||
type(cx), parameter :: tvals(*) = [cx(1,-1),cx(2,-2),cx(3,-3)]
|
||||
real, parameter :: expect(*) = tvals% re
|
||||
type(cx) , target :: tref(size(cvals)) = tvals ! Reference
|
||||
type(cx), allocatable, target :: tarr(:)
|
||||
|
||||
real, pointer :: rr1(:), rr2(:), rr3(:), rr4(:)
|
||||
class(*), pointer :: cp1(:), cp2(:), cp3(:), cp4(:)
|
||||
|
||||
carr = cvals
|
||||
tarr = tvals
|
||||
|
||||
if (any (expect /= [1,2,3])) error stop 90
|
||||
|
||||
! REAL pointer to non-contiguous effective target
|
||||
rr1(1:3) => cref%re
|
||||
rr2 => cref%re
|
||||
rr3(1:3) => carr%re
|
||||
rr4 => carr%re
|
||||
|
||||
if (is_contiguous (rr1)) stop 1
|
||||
if (my_contiguous_real (rr1)) stop 2
|
||||
if (is_contiguous (cref(1:3)%re)) stop 3
|
||||
! if (my_contiguous_real (cref(1:3)%re)) stop 4 ! pr122397
|
||||
|
||||
if (is_contiguous (rr3)) stop 6
|
||||
if (my_contiguous_real (rr3)) stop 7
|
||||
if (is_contiguous (carr(1:3)%re)) stop 8
|
||||
! if (my_contiguous_real (carr(1:3)%re)) stop 9
|
||||
|
||||
if (is_contiguous (rr2)) stop 11
|
||||
if (my_contiguous_real (rr2)) stop 12
|
||||
if (is_contiguous (cref%re)) stop 13
|
||||
! if (my_contiguous_real (cref%re)) stop 14
|
||||
|
||||
if (is_contiguous (rr4)) stop 16
|
||||
if (my_contiguous_real (rr4)) stop 17
|
||||
if (is_contiguous (carr%re)) stop 18
|
||||
! if (my_contiguous_real (carr%re)) stop 19
|
||||
|
||||
rr1(1:3) => tref%re
|
||||
rr2 => tref%re
|
||||
rr3(1:3) => tarr%re
|
||||
rr4 => tarr%re
|
||||
|
||||
if (is_contiguous (rr1)) stop 21
|
||||
if (my_contiguous_real (rr1)) stop 22
|
||||
if (is_contiguous (tref(1:3)%re)) stop 23
|
||||
! if (my_contiguous_real (tref(1:3)%re)) stop 24
|
||||
|
||||
if (is_contiguous (rr3)) stop 26
|
||||
if (my_contiguous_real (rr3)) stop 27
|
||||
if (is_contiguous (tarr(1:3)%re)) stop 28
|
||||
! if (my_contiguous_real (tarr(1:3)%re)) stop 29
|
||||
|
||||
if (is_contiguous (rr2)) stop 31
|
||||
if (my_contiguous_real (rr2)) stop 32
|
||||
if (is_contiguous (tref%re)) stop 33
|
||||
! if (my_contiguous_real (tref%re)) stop 34
|
||||
|
||||
if (is_contiguous (rr4)) stop 36
|
||||
if (my_contiguous_real (rr4)) stop 37
|
||||
if (is_contiguous (tarr%re)) stop 38
|
||||
! if (my_contiguous_real (tarr%re)) stop 39
|
||||
|
||||
! Unlimited polymorphic pointer to non-contiguous effective target
|
||||
cp1(1:3) => cref%re
|
||||
cp2 => cref%re
|
||||
cp3(1:3) => carr%re
|
||||
cp4 => carr%re
|
||||
|
||||
if (is_contiguous (cp1)) stop 41
|
||||
if (my_contiguous_poly (cp1)) stop 42
|
||||
if (is_contiguous (cp2)) stop 43
|
||||
if (my_contiguous_poly (cp2)) stop 44
|
||||
if (is_contiguous (cp3)) stop 45
|
||||
if (my_contiguous_poly (cp3)) stop 46
|
||||
if (is_contiguous (cp4)) stop 47
|
||||
if (my_contiguous_poly (cp4)) stop 48
|
||||
|
||||
cp1(1:3) => tref%re
|
||||
cp2 => tref%re
|
||||
cp3(1:3) => tarr%re
|
||||
cp4 => tarr%re
|
||||
|
||||
if (is_contiguous (cp1)) stop 51
|
||||
if (my_contiguous_poly (cp1)) stop 52
|
||||
if (is_contiguous (cp2)) stop 53
|
||||
if (my_contiguous_poly (cp2)) stop 54
|
||||
if (is_contiguous (cp3)) stop 55
|
||||
if (my_contiguous_poly (cp3)) stop 56
|
||||
if (is_contiguous (cp4)) stop 57
|
||||
if (my_contiguous_poly (cp4)) stop 58
|
||||
|
||||
deallocate (carr, tarr)
|
||||
contains
|
||||
pure logical function my_contiguous_real (x) result (res)
|
||||
real, pointer, intent(in) :: x(:)
|
||||
res = is_contiguous (x)
|
||||
if (any (x /= expect)) error stop 97
|
||||
end function my_contiguous_real
|
||||
|
||||
pure logical function my_contiguous_poly (x) result (res)
|
||||
class(*), pointer, intent(in) :: x(:)
|
||||
res = is_contiguous (x)
|
||||
select type (x)
|
||||
type is (real)
|
||||
if (any (x /= expect)) error stop 98
|
||||
class default
|
||||
error stop 99
|
||||
end select
|
||||
end function my_contiguous_poly
|
||||
end
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
! { dg-do run }
|
||||
! { dg-additional-options "-O2 -fdump-tree-optimized" }
|
||||
!
|
||||
! PR fortran/122386 - passing of component ref of nested DT array to TRANSFER
|
||||
|
||||
program main
|
||||
implicit none
|
||||
integer, parameter :: dp = 4
|
||||
|
||||
type cx
|
||||
real(dp) :: re, im
|
||||
end type cx
|
||||
|
||||
type complex_wrap1
|
||||
type(cx) :: z(2)
|
||||
end type complex_wrap1
|
||||
|
||||
type complex_wrap2
|
||||
type(cx), dimension(:), allocatable :: z
|
||||
end type complex_wrap2
|
||||
|
||||
type(complex_wrap1) :: x = complex_wrap1([cx(1,2), cx(3,4)])
|
||||
type(complex_wrap2) :: w
|
||||
|
||||
w%z = x%z
|
||||
|
||||
! The following statements should get optimized away...
|
||||
if (size (transfer ( x%z%re ,[1.0_dp])) /= 2) error stop 1
|
||||
if (size (transfer ((x%z%re),[1.0_dp])) /= 2) error stop 2
|
||||
if (size (transfer ([x%z%re],[1.0_dp])) /= 2) error stop 3
|
||||
if (size (transfer ( x%z%im ,[1.0_dp])) /= 2) error stop 4
|
||||
if (size (transfer ((x%z%im),[1.0_dp])) /= 2) error stop 5
|
||||
if (size (transfer ([x%z%im],[1.0_dp])) /= 2) error stop 6
|
||||
|
||||
! ... while the following may not:
|
||||
if (any (transfer ( x%z%re ,[1.0_dp]) /= x%z%re)) stop 7
|
||||
if (any (transfer ( x%z%im ,[1.0_dp]) /= x%z%im)) stop 8
|
||||
|
||||
if (size (transfer ( w%z%re ,[1.0_dp])) /= 2) stop 11
|
||||
if (size (transfer ((w%z%re),[1.0_dp])) /= 2) stop 12
|
||||
if (size (transfer ([w%z%re],[1.0_dp])) /= 2) stop 13
|
||||
if (size (transfer ( w%z%im ,[1.0_dp])) /= 2) stop 14
|
||||
if (size (transfer ((w%z%im),[1.0_dp])) /= 2) stop 15
|
||||
if (size (transfer ([w%z%im],[1.0_dp])) /= 2) stop 16
|
||||
|
||||
if (any (transfer ( w%z%re ,[1.0_dp]) /= x%z%re)) stop 17
|
||||
if (any (transfer ( w%z%im ,[1.0_dp]) /= x%z%im)) stop 18
|
||||
|
||||
deallocate (w%z)
|
||||
end program main
|
||||
|
||||
! { dg-final { scan-tree-dump-not "_gfortran_error_stop_numeric" "optimized" } }
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
! { dg-do compile }
|
||||
! { dg-additional-options "-O2 -march=armv8.3-a" }
|
||||
|
||||
subroutine c_add_ab(n, a, c, b) ! C += A * B
|
||||
use iso_fortran_env, only: real64
|
||||
implicit none
|
||||
!GCC$ ATTRIBUTES noinline :: c_add_ab
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) + a * b(k)
|
||||
end do
|
||||
end subroutine c_add_ab
|
||||
|
||||
subroutine c_sub_ab(n, a, c, b) ! C -= A * B
|
||||
use iso_fortran_env, only: real64
|
||||
implicit none
|
||||
!GCC$ ATTRIBUTES noinline :: c_sub_ab
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) - a * b(k)
|
||||
end do
|
||||
end subroutine c_sub_ab
|
||||
|
||||
subroutine c_add_a_conjb(n, a, c, b) ! C += A * conj(B)
|
||||
use iso_fortran_env, only: real64
|
||||
implicit none
|
||||
!GCC$ ATTRIBUTES noinline :: c_add_a_conjb
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) + a * conjg(b(k))
|
||||
end do
|
||||
end subroutine c_add_a_conjb
|
||||
|
||||
subroutine c_sub_a_conjb(n, a, c, b) ! C -= A * conj(B)
|
||||
use iso_fortran_env, only: real64
|
||||
implicit none
|
||||
!GCC$ ATTRIBUTES noinline :: c_sub_a_conjb
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) - a * conjg(b(k))
|
||||
end do
|
||||
end subroutine c_sub_a_conjb
|
||||
|
||||
! { dg-final { scan-assembler-times {fcmla\s+v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, #0} 2 } }
|
||||
! { dg-final { scan-assembler-times {fcmla\s+v[0-9]+.2d, v[0-9]+.2d, v[0-9]+.2d, #270} 2 } }
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
! { dg-do run }
|
||||
! { dg-additional-options "-O2" }
|
||||
! { dg-additional-options "-O2 -march=armv8.3-a" { target arm_v8_3a_complex_neon_hw } }
|
||||
|
||||
module util
|
||||
use iso_fortran_env, only: real64, int64
|
||||
implicit none
|
||||
contains
|
||||
pure logical function bitwise_eq(x, y)
|
||||
complex(real64), intent(in) :: x, y
|
||||
integer(int64) :: xr, xi, yr, yi
|
||||
xr = transfer(real(x,kind=real64), 0_int64)
|
||||
xi = transfer(aimag(x), 0_int64)
|
||||
yr = transfer(real(y,kind=real64), 0_int64)
|
||||
yi = transfer(aimag(y), 0_int64)
|
||||
bitwise_eq = (xr == yr) .and. (xi == yi)
|
||||
end function bitwise_eq
|
||||
|
||||
subroutine check_equal(tag, got, ref, nfail)
|
||||
character(*), intent(in) :: tag
|
||||
complex(real64), intent(in) :: got(:), ref(:)
|
||||
integer, intent(inout) :: nfail
|
||||
integer :: i
|
||||
do i = 1, size(got)
|
||||
if (.not. bitwise_eq(got(i), ref(i))) then
|
||||
nfail = nfail + 1
|
||||
write(*,'(A,": mismatch at i=",I0, " got=",2ES16.8," ref=",2ES16.8)') &
|
||||
trim(tag), i, real(got(i)), aimag(got(i)), real(ref(i)), aimag(ref(i))
|
||||
end if
|
||||
end do
|
||||
end subroutine check_equal
|
||||
end module util
|
||||
|
||||
module fcmla_ops
|
||||
use iso_fortran_env, only: real64
|
||||
implicit none
|
||||
contains
|
||||
subroutine c_add_ab(n, a, c, b) ! C += A * B
|
||||
!GCC$ ATTRIBUTES noinline :: c_add_ab
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) + a * b(k)
|
||||
end do
|
||||
end subroutine c_add_ab
|
||||
|
||||
subroutine c_sub_ab(n, a, c, b) ! C -= A * B
|
||||
!GCC$ ATTRIBUTES noinline :: c_sub_ab
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) - a * b(k)
|
||||
end do
|
||||
end subroutine c_sub_ab
|
||||
|
||||
subroutine c_add_a_conjb(n, a, c, b) ! C += A * conj(B)
|
||||
!GCC$ ATTRIBUTES noinline :: c_add_a_conjb
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) + a * conjg(b(k))
|
||||
end do
|
||||
end subroutine c_add_a_conjb
|
||||
|
||||
subroutine c_sub_a_conjb(n, a, c, b) ! C -= A * conj(B)
|
||||
!GCC$ ATTRIBUTES noinline :: c_sub_a_conjb
|
||||
integer, intent(in) :: n
|
||||
complex(real64), intent(in) :: a
|
||||
complex(real64), intent(inout) :: c(*)
|
||||
complex(real64), intent(in) :: b(*)
|
||||
integer :: k
|
||||
do k = 1, n
|
||||
c(k) = c(k) - a * conjg(b(k))
|
||||
end do
|
||||
end subroutine c_sub_a_conjb
|
||||
end module fcmla_ops
|
||||
|
||||
program fcmla_accum_pairs
|
||||
use iso_fortran_env, only: real64
|
||||
use util
|
||||
use fcmla_ops
|
||||
implicit none
|
||||
|
||||
integer, parameter :: n = 4
|
||||
complex(real64) :: a, b(n), c0(n)
|
||||
complex(real64) :: c_add_ab_got(n), c_add_ab_ref(n)
|
||||
complex(real64) :: c_sub_ab_got(n), c_sub_ab_ref(n)
|
||||
complex(real64) :: c_add_conjb_got(n), c_add_conjb_ref(n)
|
||||
complex(real64) :: c_sub_conjb_got(n), c_sub_conjb_ref(n)
|
||||
integer :: i, fails
|
||||
|
||||
! Constants (include a signed-zero lane)
|
||||
a = cmplx( 2.0_real64, -3.0_real64, kind=real64)
|
||||
b(1) = cmplx( 1.5_real64, -2.0_real64, kind=real64)
|
||||
b(2) = cmplx(-4.0_real64, 5.0_real64, kind=real64)
|
||||
b(3) = cmplx(-0.0_real64, 0.0_real64, kind=real64)
|
||||
b(4) = cmplx( 0.25_real64, 3.0_real64, kind=real64)
|
||||
|
||||
c0(1) = cmplx( 1.0_real64, -2.0_real64, kind=real64)
|
||||
c0(2) = cmplx( 3.0_real64, -4.0_real64, kind=real64)
|
||||
c0(3) = cmplx(-5.0_real64, 6.0_real64, kind=real64)
|
||||
c0(4) = cmplx( 0.0_real64, 0.0_real64, kind=real64)
|
||||
|
||||
! Run each form
|
||||
c_add_ab_got = c0; call c_add_ab (n, a, c_add_ab_got, b)
|
||||
c_sub_ab_got = c0; call c_sub_ab (n, a, c_sub_ab_got, b)
|
||||
c_add_conjb_got = c0; call c_add_a_conjb(n, a, c_add_conjb_got, b)
|
||||
c_sub_conjb_got = c0; call c_sub_a_conjb(n, a, c_sub_conjb_got, b)
|
||||
|
||||
! Scalar references
|
||||
do i = 1, n
|
||||
c_add_ab_ref(i) = c0(i) + a * b(i)
|
||||
c_sub_ab_ref(i) = c0(i) - a * b(i)
|
||||
c_add_conjb_ref(i) = c0(i) + a * conjg(b(i))
|
||||
c_sub_conjb_ref(i) = c0(i) - a * conjg(b(i))
|
||||
end do
|
||||
|
||||
! Bitwise checks
|
||||
fails = 0
|
||||
call check_equal("C += A*B ", c_add_ab_got, c_add_ab_ref, fails)
|
||||
call check_equal("C -= A*B ", c_sub_ab_got, c_sub_ab_ref, fails)
|
||||
call check_equal("C += A*conj(B) ", c_add_conjb_got, c_add_conjb_ref, fails)
|
||||
call check_equal("C -= A*conj(B) ", c_sub_conjb_got, c_sub_conjb_ref, fails)
|
||||
|
||||
if (fails == 0) then
|
||||
stop 0
|
||||
else
|
||||
stop 1
|
||||
end if
|
||||
end program fcmla_accum_pairs
|
||||
|
||||
|
|
@ -2995,10 +2995,8 @@ spaceship_replacement (basic_block cond_bb, basic_block middle_bb,
|
|||
if (has_cast_debug_uses
|
||||
|| (HONOR_NANS (TREE_TYPE (lhs1)) && !is_cast))
|
||||
{
|
||||
tree temp3 = make_node (DEBUG_EXPR_DECL);
|
||||
DECL_ARTIFICIAL (temp3) = 1;
|
||||
TREE_TYPE (temp3) = TREE_TYPE (orig_use_lhs);
|
||||
SET_DECL_MODE (temp3, TYPE_MODE (type));
|
||||
tree temp3
|
||||
= build_debug_expr_decl (TREE_TYPE (orig_use_lhs));
|
||||
if (has_cast_debug_uses)
|
||||
t = fold_convert (TREE_TYPE (temp3), temp2);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -847,15 +847,23 @@ compatible_complex_nodes_p (slp_compat_nodes_map_t *compat_cache,
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Check to see if the oprands to two multiplies, 2 each in LEFT_OP and
|
||||
RIGHT_OP match a complex multiplication or complex multiply-and-accumulate
|
||||
or complex multiply-and-subtract pattern. Do this using the permute cache
|
||||
PERM_CACHE and the combination compatibility list COMPAT_CACHE. If
|
||||
the operation is successful the macthing operands are returned in OPS and
|
||||
_STATUS indicates if the operation matched includes a conjugate of one of the
|
||||
operands. If the operation succeeds True is returned, otherwise False and
|
||||
the values in ops are meaningless. */
|
||||
static inline bool
|
||||
vect_validate_multiplication (slp_tree_to_load_perm_map_t *perm_cache,
|
||||
slp_compat_nodes_map_t *compat_cache,
|
||||
vec<slp_tree> &left_op,
|
||||
vec<slp_tree> &right_op,
|
||||
bool subtract,
|
||||
const vec<slp_tree> &left_op,
|
||||
const vec<slp_tree> &right_op,
|
||||
bool subtract, vec<slp_tree> &ops,
|
||||
enum _conj_status *_status)
|
||||
{
|
||||
auto_vec<slp_tree> ops;
|
||||
enum _conj_status stats = CONJ_NONE;
|
||||
|
||||
/* The complex operations can occur in two layouts and two permute sequences
|
||||
|
|
@ -886,31 +894,31 @@ vect_validate_multiplication (slp_tree_to_load_perm_map_t *perm_cache,
|
|||
bool neg0 = vect_match_expression_p (right_op[0], NEGATE_EXPR);
|
||||
bool neg1 = vect_match_expression_p (right_op[1], NEGATE_EXPR);
|
||||
|
||||
/* Create the combined inputs after remapping and flattening. */
|
||||
ops.create (4);
|
||||
ops.safe_splice (left_op);
|
||||
ops.safe_splice (right_op);
|
||||
|
||||
/* Determine which style we're looking at. We only have different ones
|
||||
whenever a conjugate is involved. */
|
||||
if (neg0 && neg1)
|
||||
;
|
||||
else if (neg0)
|
||||
{
|
||||
right_op[0] = SLP_TREE_CHILDREN (right_op[0])[0];
|
||||
ops[2] = SLP_TREE_CHILDREN (right_op[0])[0];
|
||||
stats = CONJ_FST;
|
||||
if (subtract)
|
||||
perm = 0;
|
||||
}
|
||||
else if (neg1)
|
||||
{
|
||||
right_op[1] = SLP_TREE_CHILDREN (right_op[1])[0];
|
||||
ops[3] = SLP_TREE_CHILDREN (right_op[1])[0];
|
||||
stats = CONJ_SND;
|
||||
perm = 1;
|
||||
}
|
||||
|
||||
*_status = stats;
|
||||
|
||||
/* Flatten the inputs after we've remapped them. */
|
||||
ops.create (4);
|
||||
ops.safe_splice (left_op);
|
||||
ops.safe_splice (right_op);
|
||||
|
||||
/* Extract out the elements to check. */
|
||||
slp_tree op0 = ops[styles[style][0]];
|
||||
slp_tree op1 = ops[styles[style][1]];
|
||||
|
|
@ -1073,15 +1081,16 @@ complex_mul_pattern::matches (complex_operation_t op,
|
|||
return IFN_LAST;
|
||||
|
||||
enum _conj_status status;
|
||||
auto_vec<slp_tree> res_ops;
|
||||
if (!vect_validate_multiplication (perm_cache, compat_cache, left_op,
|
||||
right_op, false, &status))
|
||||
right_op, false, res_ops, &status))
|
||||
{
|
||||
/* Try swapping the order and re-trying since multiplication is
|
||||
commutative. */
|
||||
std::swap (left_op[0], left_op[1]);
|
||||
std::swap (right_op[0], right_op[1]);
|
||||
if (!vect_validate_multiplication (perm_cache, compat_cache, left_op,
|
||||
right_op, false, &status))
|
||||
right_op, false, res_ops, &status))
|
||||
return IFN_LAST;
|
||||
}
|
||||
|
||||
|
|
@ -1109,24 +1118,24 @@ complex_mul_pattern::matches (complex_operation_t op,
|
|||
if (add0)
|
||||
ops->quick_push (add0);
|
||||
|
||||
complex_perm_kinds_t kind = linear_loads_p (perm_cache, left_op[0]);
|
||||
complex_perm_kinds_t kind = linear_loads_p (perm_cache, res_ops[0]);
|
||||
if (kind == PERM_EVENODD || kind == PERM_TOP)
|
||||
{
|
||||
ops->quick_push (left_op[1]);
|
||||
ops->quick_push (right_op[1]);
|
||||
ops->quick_push (left_op[0]);
|
||||
ops->quick_push (res_ops[1]);
|
||||
ops->quick_push (res_ops[3]);
|
||||
ops->quick_push (res_ops[0]);
|
||||
}
|
||||
else if (kind == PERM_EVENEVEN && status != CONJ_SND)
|
||||
{
|
||||
ops->quick_push (left_op[0]);
|
||||
ops->quick_push (right_op[0]);
|
||||
ops->quick_push (left_op[1]);
|
||||
ops->quick_push (res_ops[0]);
|
||||
ops->quick_push (res_ops[2]);
|
||||
ops->quick_push (res_ops[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ops->quick_push (left_op[0]);
|
||||
ops->quick_push (right_op[1]);
|
||||
ops->quick_push (left_op[1]);
|
||||
ops->quick_push (res_ops[0]);
|
||||
ops->quick_push (res_ops[3]);
|
||||
ops->quick_push (res_ops[1]);
|
||||
}
|
||||
|
||||
return ifn;
|
||||
|
|
@ -1298,15 +1307,17 @@ complex_fms_pattern::matches (complex_operation_t op,
|
|||
return IFN_LAST;
|
||||
|
||||
enum _conj_status status;
|
||||
auto_vec<slp_tree> res_ops;
|
||||
if (!vect_validate_multiplication (perm_cache, compat_cache, right_op,
|
||||
left_op, true, &status))
|
||||
left_op, true, res_ops, &status))
|
||||
{
|
||||
/* Try swapping the order and re-trying since multiplication is
|
||||
commutative. */
|
||||
std::swap (left_op[0], left_op[1]);
|
||||
std::swap (right_op[0], right_op[1]);
|
||||
auto_vec<slp_tree> res_ops;
|
||||
if (!vect_validate_multiplication (perm_cache, compat_cache, right_op,
|
||||
left_op, true, &status))
|
||||
left_op, true, res_ops, &status))
|
||||
return IFN_LAST;
|
||||
}
|
||||
|
||||
|
|
@ -1321,20 +1332,20 @@ complex_fms_pattern::matches (complex_operation_t op,
|
|||
ops->truncate (0);
|
||||
ops->create (4);
|
||||
|
||||
complex_perm_kinds_t kind = linear_loads_p (perm_cache, right_op[0]);
|
||||
complex_perm_kinds_t kind = linear_loads_p (perm_cache, res_ops[2]);
|
||||
if (kind == PERM_EVENODD)
|
||||
{
|
||||
ops->quick_push (l0node[0]);
|
||||
ops->quick_push (right_op[0]);
|
||||
ops->quick_push (right_op[1]);
|
||||
ops->quick_push (left_op[1]);
|
||||
ops->quick_push (res_ops[2]);
|
||||
ops->quick_push (res_ops[3]);
|
||||
ops->quick_push (res_ops[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ops->quick_push (l0node[0]);
|
||||
ops->quick_push (right_op[1]);
|
||||
ops->quick_push (right_op[0]);
|
||||
ops->quick_push (left_op[0]);
|
||||
ops->quick_push (res_ops[3]);
|
||||
ops->quick_push (res_ops[2]);
|
||||
ops->quick_push (res_ops[0]);
|
||||
}
|
||||
|
||||
return ifn;
|
||||
|
|
|
|||
Loading…
Reference in New Issue