summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/pr36922.f16
-rw-r--r--gcc/tree-data-ref.c8
-rw-r--r--gcc/tree-scalar-evolution.c27
5 files changed, 63 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index de8ed80faaa..551619115b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2009-02-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/36922
+ * tree-data-ref.c (initialize_matrix_A): Handle BIT_NOT_EXPR.
+ * tree-scalar-evolution.c (interpret_rhs_expr, instantiate_scev_1):
+ Likewise.
+
2009-02-17 Richard Sandiford <rdsandiford@googlemail.com>
* config/mips/mips.c (mips_override_options): Set flag_dwarf2_cfi_asm
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5b620d4eeac..3cbc3e79229 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-02-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/36922
+ * gfortran.dg/pr36922.f: New test.
+
2009-02-17 Richard Guenther <rguenther@suse.de>
PR tree-optimization/39202
diff --git a/gcc/testsuite/gfortran.dg/pr36922.f b/gcc/testsuite/gfortran.dg/pr36922.f
new file mode 100644
index 00000000000..6aa95beb696
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr36922.f
@@ -0,0 +1,16 @@
+C PR tree-optimization/36922
+C { dg-do compile }
+C { dg-options "-O2 -ftree-loop-linear" }
+ SUBROUTINE PR36922(N,F,Z,C)
+ IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+ DIMENSION C(23821),Z(0:2*N+1),F(0:2*N)
+ I=0
+ DO L=0,N
+ DO M=0,L
+ DO M2=M,L
+ I=I+1
+ C(I)=F(L+M)*F(L-M)*Z(L-M2)/(F(M2+M)*F(M2-M)*F(L-M2)*F(L-M2))
+ ENDDO
+ ENDDO
+ ENDDO
+ END
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 2715339219e..9a72bc348b8 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -1896,6 +1896,14 @@ initialize_matrix_A (lambda_matrix A, tree chrec, unsigned index, int mult)
return chrec_convert (chrec_type (chrec), op, NULL);
}
+ case BIT_NOT_EXPR:
+ {
+ /* Handle ~X as -1 - X. */
+ tree op = initialize_matrix_A (A, TREE_OPERAND (chrec, 0), index, mult);
+ return chrec_fold_op (MINUS_EXPR, chrec_type (chrec),
+ build_int_cst (TREE_TYPE (chrec), -1), op);
+ }
+
case INTEGER_CST:
return chrec;
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index f306ab8277c..ba15d52c68d 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -1712,6 +1712,15 @@ interpret_rhs_expr (struct loop *loop, gimple at_stmt,
fold_convert (type, integer_minus_one_node));
break;
+ case BIT_NOT_EXPR:
+ /* Handle ~X as -1 - X. */
+ chrec1 = analyze_scalar_evolution (loop, rhs1);
+ chrec1 = chrec_convert (type, chrec1, at_stmt);
+ res = chrec_fold_minus (type,
+ fold_convert (type, integer_minus_one_node),
+ chrec1);
+ break;
+
case MULT_EXPR:
chrec1 = analyze_scalar_evolution (loop, rhs1);
chrec2 = analyze_scalar_evolution (loop, rhs2);
@@ -2215,6 +2224,24 @@ instantiate_scev_1 (basic_block instantiate_below,
return chrec_convert (TREE_TYPE (chrec), op0, NULL);
+ case BIT_NOT_EXPR:
+ /* Handle ~X as -1 - X. */
+ op0 = instantiate_scev_1 (instantiate_below, evolution_loop,
+ TREE_OPERAND (chrec, 0),
+ fold_conversions, cache, size_expr);
+ if (op0 == chrec_dont_know)
+ return chrec_dont_know;
+
+ if (TREE_OPERAND (chrec, 0) != op0)
+ {
+ op0 = chrec_convert (type, op0, NULL);
+ chrec = chrec_fold_minus (type,
+ fold_convert (type,
+ integer_minus_one_node),
+ op0);
+ }
+ return chrec;
+
case SCEV_NOT_KNOWN:
return chrec_dont_know;