Hi,

since we construct arithmetic jump functions even when there is a
type conversion in between the operation encoded in the jump function
and when it is passed in a call argument, the IPA propagation phase
must also perform the operation and conversion in two steps.  IPA-VR
had actually been doing it even before for binary operations but, as
PR 118756 exposes, not in the case on unary operations.  This patch
adds the necessary step to rectify that.

Like in the scalar constant case, we depend on
expr_type_first_operand_type_p to determine the type of the result of
the arithmetic operation.  On top this, the patch special-cases
ABSU_EXPR because it looks useful an so that the PR testcase exercises
the added code-path.  This seems most appropriate for stage 4, long
term we should probably stream the types, probably after also encoding
them with a string of expr_eval_op rather than what we have today.

A check for expr_type_first_operand_type_p was also missing in the
handling of binary ops and the intermediate value_range was
initialized with a wrong type, so I also fixed this.

Bootstrapped and LTO-bootstrapped and tested on x86_64-linux.  OK for
master?

Thanks,

Martin



gcc/ChangeLog:

2025-02-24  Martin Jambor  <mjam...@suse.cz>

        PR ipa/118785

        * ipa-cp.cc (ipa_vr_intersect_with_arith_jfunc): Handle non-conversion
        unary operations separately before doing any conversions.  Check
        expr_type_first_operand_type_p for non-unary operations too.  Fix type
        of op_res.

gcc/testsuite/ChangeLog:

2025-02-24  Martin Jambor  <mjam...@suse.cz>

        PR ipa/118785
        * g++.dg/lto/pr118785_0.C: New test.
---
 gcc/ipa-cp.cc                         | 34 ++++++++++++++++++++++++---
 gcc/testsuite/g++.dg/lto/pr118785_0.C | 14 +++++++++++
 2 files changed, 45 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/lto/pr118785_0.C

diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
index 68959f2677b..0dd65a707b6 100644
--- a/gcc/ipa-cp.cc
+++ b/gcc/ipa-cp.cc
@@ -1720,8 +1720,34 @@ ipa_vr_intersect_with_arith_jfunc (vrange &vr,
   enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
   if (TREE_CODE_CLASS (operation) == tcc_unary)
     {
+      value_range op_res;
+      const value_range *inter_vr;
+      if (operation != NOP_EXPR)
+       {
+         tree operation_type;
+         if (expr_type_first_operand_type_p (operation))
+           operation_type = src_type;
+         else if (operation == ABSU_EXPR)
+           operation_type = unsigned_type_for (src_type);
+         else
+           return;
+         op_res.set_varying (operation_type);
+         if (!ipa_vr_operation_and_type_effects (op_res, src_vr, operation,
+                                                 operation_type, src_type))
+           return;
+         if (src_type == dst_type)
+           {
+             vr.intersect (op_res);
+             return;
+           }
+         inter_vr = &op_res;
+         src_type = operation_type;
+       }
+      else
+       inter_vr = &src_vr;
+
       value_range tmp_res (dst_type);
-      if (ipa_vr_operation_and_type_effects (tmp_res, src_vr, operation,
+      if (ipa_vr_operation_and_type_effects (tmp_res, *inter_vr, NOP_EXPR,
                                             dst_type, src_type))
        vr.intersect (tmp_res);
       return;
@@ -1737,10 +1763,12 @@ ipa_vr_intersect_with_arith_jfunc (vrange &vr,
   tree operation_type;
   if (TREE_CODE_CLASS (operation) == tcc_comparison)
     operation_type = boolean_type_node;
-  else
+  else if (expr_type_first_operand_type_p (operation))
     operation_type = src_type;
+  else
+    return;
 
-  value_range op_res (dst_type);
+  value_range op_res (operation_type);
   if (!ipa_vr_supported_type_p (operation_type)
       || !handler.operand_check_p (operation_type, src_type, op_vr.type ())
       || !handler.fold_range (op_res, operation_type, src_vr, op_vr))
diff --git a/gcc/testsuite/g++.dg/lto/pr118785_0.C 
b/gcc/testsuite/g++.dg/lto/pr118785_0.C
new file mode 100644
index 00000000000..9b99c7d9210
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr118785_0.C
@@ -0,0 +1,14 @@
+// { dg-lto-do link }
+// { dg-require-effective-target fpic }x
+// { dg-lto-options { "-O3 -flto -fPIC" } }
+
+void WriteLiteral( unsigned long data, unsigned long bits) {}
+void WriteQIndexDelta( short qDelta)
+{
+  WriteLiteral(__builtin_abs(qDelta), 4);
+}
+__attribute((used))
+void ff(signed char *qIndexDeltaLumaDC) {
+  WriteQIndexDelta(*qIndexDeltaLumaDC);
+}
+int main(){}
-- 
2.47.1

Reply via email to