summaryrefslogtreecommitdiffstats
path: root/debian/patches/pr113705.diff
blob: 8ca12df455b26896a911e7c8d870c2795b590286 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# DP: Proposed patch for PR middle-end/113705

2024-02-01  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/113705
	* tree-ssa-math-opts.cc (is_widening_mult_rhs_p): Use wide_int_from
	around wi::to_wide in order to compare value in prec precision.

	* g++.dg/opt/pr113705.C: New test.

--- a/src/gcc/tree-ssa-math-opts.cc
+++ b/src/gcc/tree-ssa-math-opts.cc
@@ -2572,7 +2572,8 @@ is_widening_mult_rhs_p (tree type, tree
 	      if (is_gimple_assign (stmt)
 		  && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
 		  && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
-		  && wi::to_wide (gimple_assign_rhs2 (stmt))
+		  && wide_int::from (wi::to_wide (gimple_assign_rhs2 (stmt)),
+				     prec, TYPE_SIGN (TREE_TYPE (rhs)))
 		     == wi::mask (hprec, false, prec))
 		*new_rhs_out = gimple_assign_rhs1 (stmt);
 	      else
--- a/src/gcc/testsuite/g++.dg/opt/pr113705.C
+++ b/src/gcc/testsuite/g++.dg/opt/pr113705.C
@@ -0,0 +1,68 @@
+// PR middle-end/113705
+// { dg-do compile { target c++17 } }
+// { dg-options "-O2 -w" }
+
+void foo ();
+template <typename T> struct A : T { long bar () const; };
+int a;
+
+template <typename T>
+long
+A<T>::bar () const
+{
+  return this->baz ()[a];
+}
+
+struct B {
+  struct { long b[1]; long c; } u;
+  unsigned d;
+  int e;
+  B (const B &);
+  ~B ();
+  const long *baz () const;
+  unsigned qux () const;
+};
+
+B::B (const B &)
+{
+  if (__builtin_expect (e, 0))
+    u.c = 0;
+}
+
+B::~B ()
+{
+  if (__builtin_expect (e, 0))
+    foo ();
+}
+
+const long *
+B::baz () const
+{
+  return u.b;
+}
+
+unsigned
+B::qux () const
+{
+  return d;
+}
+
+struct C { A<B> corge () const; A<B> *f; };
+
+A<B>
+C::corge () const
+{
+  return f[1];
+}
+
+void
+test (C r, long *h, unsigned short *d)
+{
+  for (int j = 0; j < 8; ++j)
+    {
+      A g = r.corge ();
+      *d = g.qux ();
+      for (unsigned i = 0; i < *d; ++i)
+	*h++ = g.bar ();
+    }
+}