aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2019-01-08 15:45:28 +0100
committerMartin Liska <marxin@gcc.gnu.org>2019-01-08 14:45:28 +0000
commit5a5474ba24dad14f32e2adfa5fe4d8431df77d4e (patch)
treeb7808b55c647dd4727ac91fc6e9db04df57390e1
parent9f5391ee9521e90d0f3b545893d9d4b3d98839d1 (diff)
downloadgcc-5a5474ba24dad14f32e2adfa5fe4d8431df77d4e.zip
gcc-5a5474ba24dad14f32e2adfa5fe4d8431df77d4e.tar.gz
gcc-5a5474ba24dad14f32e2adfa5fe4d8431df77d4e.tar.bz2
Use proper type in linear transformation in tree-switch-conversion (PR tree-optimization/88753).
2019-01-08 Martin Liska <mliska@suse.cz> PR tree-optimization/88753 * tree-switch-conversion.c (switch_conversion::build_one_array): Come up with local variable constructor. Convert first to type of constructor values. 2019-01-08 Martin Liska <mliska@suse.cz> PR tree-optimization/88753 * gcc.dg/tree-ssa/pr88753.c: New test. From-SVN: r267728
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr88753.c57
-rw-r--r--gcc/tree-switch-conversion.c17
4 files changed, 79 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bc313e1..c512ff4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2019-01-08 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/88753
+ * tree-switch-conversion.c (switch_conversion::build_one_array):
+ Come up with local variable constructor. Convert first to
+ type of constructor values.
+
2019-01-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/86554
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 98a851c..c53bf5a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2019-01-08 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/88753
+ * gcc.dg/tree-ssa/pr88753.c: New test.
+
2019-01-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/86554
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr88753.c b/gcc/testsuite/gcc.dg/tree-ssa/pr88753.c
new file mode 100644
index 0000000..eaefc38
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr88753.c
@@ -0,0 +1,57 @@
+/* PR tree-optimization/88753 */
+/* { dg-options "-O2 -fdump-tree-switchconv" } */
+/* { dg-do run { target nonpic } } */
+
+typedef unsigned short int uint16_t;
+typedef unsigned char uint8_t;
+
+uint16_t length;
+uint16_t enc_method_global;
+
+uint8_t
+__attribute__((noipa))
+_zip_buffer_get_8(int buffer)
+{
+ return buffer;
+}
+
+ int
+ __attribute__((noipa))
+foo(int v)
+{
+ uint16_t enc_method;
+ switch (_zip_buffer_get_8(v)) {
+ case 1:
+ enc_method = 0x0101;
+ break;
+ case 2:
+ enc_method = 0x0102;
+ break;
+ case 3:
+ enc_method = 0x0103;
+ break;
+ default:
+ __builtin_abort ();
+ }
+
+ enc_method_global = enc_method;
+}
+
+int main(int argc, char **argv)
+{
+ foo (1);
+ if (enc_method_global != 0x0101)
+ __builtin_abort ();
+
+ foo (2);
+ if (enc_method_global != 0x0102)
+ __builtin_abort ();
+
+ foo (3);
+ if (enc_method_global != 0x0103)
+ __builtin_abort ();
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Linear transformation with A = 1 and B = 256" 1 "switchconv" } } */
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 614c450..c3f2baf 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -473,8 +473,10 @@ switch_conversion::contains_linear_function_p (vec<constructor_elt, va_gc> *vec,
if (TREE_CODE (elt0) != INTEGER_CST || TREE_CODE (elt1) != INTEGER_CST)
return false;
- wide_int range_min = wi::to_wide (fold_convert (TREE_TYPE (elt0),
- m_range_min));
+ wide_int range_min
+ = wide_int::from (wi::to_wide (m_range_min),
+ TYPE_PRECISION (TREE_TYPE (elt0)),
+ TYPE_SIGN (TREE_TYPE (m_range_min)));
wide_int y1 = wi::to_wide (elt0);
wide_int y2 = wi::to_wide (elt1);
wide_int a = y2 - y1;
@@ -600,9 +602,9 @@ switch_conversion::build_one_array (int num, tree arr_index_type,
name = copy_ssa_name (PHI_RESULT (phi));
m_target_inbound_names[num] = name;
+ vec<constructor_elt, va_gc> *constructor = m_constructors[num];
wide_int coeff_a, coeff_b;
- bool linear_p = contains_linear_function_p (m_constructors[num], &coeff_a,
- &coeff_b);
+ bool linear_p = contains_linear_function_p (constructor, &coeff_a, &coeff_b);
if (linear_p)
{
if (dump_file && coeff_a.to_uhwi () > 0)
@@ -610,7 +612,8 @@ switch_conversion::build_one_array (int num, tree arr_index_type,
" and B = %" PRId64 "\n", coeff_a.to_shwi (),
coeff_b.to_shwi ());
- tree t = unsigned_type_for (TREE_TYPE (m_index_expr));
+ /* We must use type of constructor values. */
+ tree t = unsigned_type_for (TREE_TYPE ((*constructor)[0].value));
gimple_seq seq = NULL;
tree tmp = gimple_convert (&seq, t, m_index_expr);
tree tmp2 = gimple_build (&seq, MULT_EXPR, t,
@@ -633,10 +636,10 @@ switch_conversion::build_one_array (int num, tree arr_index_type,
unsigned int i;
constructor_elt *elt;
- FOR_EACH_VEC_SAFE_ELT (m_constructors[num], i, elt)
+ FOR_EACH_VEC_SAFE_ELT (constructor, i, elt)
elt->value = fold_convert (value_type, elt->value);
}
- ctor = build_constructor (array_type, m_constructors[num]);
+ ctor = build_constructor (array_type, constructor);
TREE_CONSTANT (ctor) = true;
TREE_STATIC (ctor) = true;