diff options
-rw-r--r-- | gcc/config/riscv/riscv-c.cc | 3 | ||||
-rw-r--r-- | gcc/doc/generic.texi | 9 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/pr104140.c | 11 | ||||
-rw-r--r-- | gcc/tree-ssa-math-opts.cc | 4 | ||||
-rw-r--r-- | gcc/tree.def | 14 |
5 files changed, 36 insertions, 5 deletions
diff --git a/gcc/config/riscv/riscv-c.cc b/gcc/config/riscv/riscv-c.cc index 211472f..73c62f4 100644 --- a/gcc/config/riscv/riscv-c.cc +++ b/gcc/config/riscv/riscv-c.cc @@ -108,6 +108,9 @@ riscv_cpu_cpp_builtins (cpp_reader *pfile) builtin_define_with_int_value ("__riscv_arch_test", 1); const riscv_subset_list *subset_list = riscv_current_subset_list (); + if (!subset_list) + return; + size_t max_ext_len = 0; /* Figure out the max length of extension name for reserving buffer. */ diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi index 3e5b06a..e5f9d1b 100644 --- a/gcc/doc/generic.texi +++ b/gcc/doc/generic.texi @@ -1318,6 +1318,7 @@ The type of the node specifies the alignment of the access. @tindex PLUS_EXPR @tindex MINUS_EXPR @tindex MULT_EXPR +@tindex WIDEN_MULT_EXPR @tindex MULT_HIGHPART_EXPR @tindex RDIV_EXPR @tindex TRUNC_DIV_EXPR @@ -1532,10 +1533,18 @@ one operand is of floating type and the other is of integral type. The behavior of these operations on signed arithmetic overflow is controlled by the @code{flag_wrapv} and @code{flag_trapv} variables. +@item WIDEN_MULT_EXPR +This node represents a widening multiplication. The operands have +integral types with same @var{b} bits of precision, producing an +integral type result with at least @math{2@var{b}} bits of precision. +The behaviour is equivalent to extending both operands, possibly of +different signedness, to the result type, then multiplying them. + @item MULT_HIGHPART_EXPR This node represents the ``high-part'' of a widening multiplication. For an integral type with @var{b} bits of precision, the result is the most significant @var{b} bits of the full @math{2@var{b}} product. +Both operands must have the same precision and same signedness. @item RDIV_EXPR This node represents a floating point division operation. diff --git a/gcc/testsuite/gcc.target/riscv/pr104140.c b/gcc/testsuite/gcc.target/riscv/pr104140.c new file mode 100644 index 0000000..648e131 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/pr104140.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -march=rv32im -mabi=ilp32" } */ +int x; +unsigned u, v; +void f (void) +{ + long long y = x; + u = y * v >> 32; +} +void g (void) { f (); } + diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc index 3d7104a..ac27775 100644 --- a/gcc/tree-ssa-math-opts.cc +++ b/gcc/tree-ssa-math-opts.cc @@ -4608,6 +4608,10 @@ convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi) if (bits < prec || bits >= 2 * prec) return false; + /* For the time being, require operands to have the same sign. */ + if (unsignedp != TYPE_UNSIGNED (TREE_TYPE (mop2))) + return false; + machine_mode mode = TYPE_MODE (optype); optab tab = unsignedp ? umul_highpart_optab : smul_highpart_optab; if (optab_handler (tab, mode) == CODE_FOR_nothing) diff --git a/gcc/tree.def b/gcc/tree.def index bd43dbc..62650b6 100644 --- a/gcc/tree.def +++ b/gcc/tree.def @@ -700,7 +700,9 @@ DEFTREECODE (POINTER_PLUS_EXPR, "pointer_plus_expr", tcc_binary, 2) DEFTREECODE (POINTER_DIFF_EXPR, "pointer_diff_expr", tcc_binary, 2) /* Highpart multiplication. For an integral type with precision B, - returns bits [2B-1, B] of the full 2*B product. */ + returns bits [2B-1, B] of the full 2*B product. Both operands + and the result should have integer types of the same precision + and signedness. */ DEFTREECODE (MULT_HIGHPART_EXPR, "mult_highpart_expr", tcc_binary, 2) /* Division for integer result that rounds the quotient toward zero. */ @@ -1349,10 +1351,12 @@ DEFTREECODE (WIDEN_SUM_EXPR, "widen_sum_expr", tcc_binary, 2) DEFTREECODE (SAD_EXPR, "sad_expr", tcc_expression, 3) /* Widening multiplication. - The two arguments are of type t1. - The result is of type t2, such that t2 is at least twice - the size of t1. WIDEN_MULT_EXPR is equivalent to first widening (promoting) - the arguments from type t1 to type t2, and then multiplying them. */ + The two arguments are of type t1 and t2, both integral types that + have the same precision, but possibly different signedness. + The result is of integral type t3, such that t3 is at least twice + the size of t1/t2. WIDEN_MULT_EXPR is equivalent to first widening + (promoting) the arguments from type t1 to type t3, and from t2 to + type t3 and then multiplying them. */ DEFTREECODE (WIDEN_MULT_EXPR, "widen_mult_expr", tcc_binary, 2) /* Widening multiply-accumulate. |