summaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99465.patch
blob: 32c2999a7c0d65b7672fe9f0e65a728feb9a8a2c (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
94
2011-01-18  Ulrich Weigand  <uweigand@de.ibm.com>

	LP: #685352
	Backport from mainline:

	2011-01-18  Jakub Jelinek  <jakub@redhat.com>

	gcc/
	PR rtl-optimization/47299
	* expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Don't use
	subtarget.  Use normal multiplication if both operands are
	constants.
	* expmed.c (expand_widening_mult): Don't try to optimize constant
	multiplication if op0 has VOIDmode.  Convert op1 constant to mode
	before using it.

	gcc/testsuite/
	PR rtl-optimization/47299
	* gcc.c-torture/execute/pr47299.c: New test.

=== modified file 'gcc/expmed.c'
Index: gcc-4_5-branch/gcc/expmed.c
===================================================================
--- gcc-4_5-branch.orig/gcc/expmed.c
+++ gcc-4_5-branch/gcc/expmed.c
@@ -3355,12 +3355,17 @@ expand_widening_mult (enum machine_mode 
 		      int unsignedp, optab this_optab)
 {
   bool speed = optimize_insn_for_speed_p ();
+  rtx cop1;
 
   if (CONST_INT_P (op1)
-      && (INTVAL (op1) >= 0
+      && GET_MODE (op0) != VOIDmode
+      && (cop1 = convert_modes (mode, GET_MODE (op0), op1,
+				this_optab == umul_widen_optab))
+      && CONST_INT_P (cop1)
+      && (INTVAL (cop1) >= 0
 	  || GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT))
     {
-      HOST_WIDE_INT coeff = INTVAL (op1);
+      HOST_WIDE_INT coeff = INTVAL (cop1);
       int max_cost;
       enum mult_variant variant;
       struct algorithm algorithm;
Index: gcc-4_5-branch/gcc/expr.c
===================================================================
--- gcc-4_5-branch.orig/gcc/expr.c
+++ gcc-4_5-branch/gcc/expr.c
@@ -7624,10 +7624,10 @@ expand_expr_real_2 (sepops ops, rtx targ
 	      if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)
 		{
 		  if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
-		    expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
+		    expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
 				     EXPAND_NORMAL);
 		  else
-		    expand_operands (treeop0, treeop1, subtarget, &op1, &op0,
+		    expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
 				     EXPAND_NORMAL);
 		  goto binop3;
 		}
@@ -7645,7 +7645,8 @@ expand_expr_real_2 (sepops ops, rtx targ
 	  optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
 	  this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
 
-	  if (mode == GET_MODE_2XWIDER_MODE (innermode))
+	  if (mode == GET_MODE_2XWIDER_MODE (innermode)
+	      && TREE_CODE (treeop0) != INTEGER_CST)
 	    {
 	      if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)
 		{
Index: gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c
===================================================================
--- /dev/null
+++ gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c
@@ -0,0 +1,17 @@
+/* PR rtl-optimization/47299 */
+
+extern void abort (void);
+
+__attribute__ ((noinline, noclone)) unsigned short
+foo (unsigned char x)
+{
+  return x * 255;
+}
+
+int
+main ()
+{
+  if (foo (0x40) != 0x3fc0)
+    abort ();
+  return 0;
+}