summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/m68k/m68k.md4
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr60822.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr60822.x7
5 files changed, 46 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a29383083b3..6100b75683b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-04-24 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/60822
+ * config/m68k/m68k.md (extendplussidi): Don't allow memory for
+ operand 1.
+
2014-04-24 Dimitris Papavasiliou <dpapavas@gmail.com>
* flag-types.h (enum ivar_visibility): Add.
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index e61048b4d0b..72c11f592db 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -1868,9 +1868,11 @@
;; Maybe there is a way to make that the general case, by forcing the
;; result of the SI tree to be in the lower register of the DI target
+;; Don't allow memory for operand 1 as that would require an earlyclobber
+;; which results in worse code
(define_insn "extendplussidi"
[(set (match_operand:DI 0 "register_operand" "=d")
- (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
+ (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rn")
(match_operand:SI 2 "general_operand" "rmn"))))]
""
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 32cccf27185..413d6ce8615 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-04-24 Jeff Law <law@redhat.com>
+
+ PR target/60822
+ * gcc.c-torture/pr60822.c: New test.
+ * gcc.c-torture/pr60822.x: New test.
+
2014-04-24 Dinar Temirbulatov <dtemirbulatov@gmail.com>
PR c++/57958
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60822.c b/gcc/testsuite/gcc.c-torture/execute/pr60822.c
new file mode 100644
index 00000000000..d2253310e69
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr60822.c
@@ -0,0 +1,24 @@
+struct X {
+ char fill0[800000];
+ int a;
+ char fill1[900000];
+ int b;
+};
+
+int __attribute__((noinline,noclone))
+Avg(struct X *p, int s)
+{
+ return (s * (long long)(p->a + p->b)) >> 17;
+}
+
+struct X x;
+
+int main()
+{
+ x.a = 1 << 17;
+ x.b = 2 << 17;
+ if (Avg(&x, 1) != 3)
+ __builtin_abort();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60822.x b/gcc/testsuite/gcc.c-torture/execute/pr60822.x
new file mode 100644
index 00000000000..4efed4c325f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr60822.x
@@ -0,0 +1,7 @@
+load_lib target-supports.exp
+
+if { [check_effective_target_int32plus] } {
+ return 0
+}
+
+return 1;