summaryrefslogtreecommitdiff
blob: 762d198f4cfd0f64534abfca99d27d4a7b034891 (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
2002-10-30  Jan Hubicka  <jh@suse.cz>
	
	PR target/8213
	* config/i386/i386.c (ix86_expand_int_movcc): Fix RTL sharing problem.

2002-11-04  Gwenole Beauchesne  <gbeauchesne@mandrakesoft.com>

	* testsuite/gcc.c-torture/execute/20021104.c: New test.

--- gcc-3.2/gcc/config/i386/i386.c.pr8213	2002-11-04 12:56:37.000000000 -0500
+++ gcc-3.2/gcc/config/i386/i386.c	2002-11-04 13:21:22.000000000 -0500
@@ -8274,11 +8274,11 @@ ix86_expand_int_movcc (operands)
 	  /* On x86_64 the lea instruction operates on Pmode, so we need to get arithmetics
 	     done in proper mode to match.  */
 	  if (diff == 1)
-	    tmp = out;
+	    tmp = copy_rtx (out);
 	  else
 	    {
 	      rtx out1;
-	      out1 = out;
+	      out1 = copy_rtx (out);
 	      tmp = gen_rtx_MULT (mode, out1, GEN_INT (diff & ~1));
 	      nops++;
 	      if (diff & 1)
@@ -8302,12 +8302,12 @@ ix86_expand_int_movcc (operands)
 		  clob = gen_rtx_REG (CCmode, FLAGS_REG);
 		  clob = gen_rtx_CLOBBER (VOIDmode, clob);
 
-		  tmp = gen_rtx_SET (VOIDmode, out, tmp);
+		  tmp = gen_rtx_SET (VOIDmode, copy_rtx (out), tmp);
 		  tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, copy_rtx (tmp), clob));
 		  emit_insn (tmp);
 		}
 	      else
-		emit_insn (gen_rtx_SET (VOIDmode, out, tmp));
+		emit_insn (gen_rtx_SET (VOIDmode, copy_rtx (out), tmp));
 	    }
 	  if (out != operands[0])
 	    emit_move_insn (operands[0], copy_rtx (out));
--- gcc-3.2/gcc/testsuite/gcc.c-torture/execute/20021104.c.pr8213	2002-11-04 13:22:33.000000000 -0500
+++ gcc-3.2/gcc/testsuite/gcc.c-torture/execute/20021104.c	2002-11-04 13:24:12.000000000 -0500
@@ -0,0 +1,26 @@
+/* PR target/8213
+   This testcase, distilled from GNU gmp 4.1, was miscompiled on x86-64
+   because of RTL sharing problems.  */
+
+int f(long x, long y)
+{
+  if ((x < 0) == (y < 0))
+    {
+      if (x == 0)
+        return -(y != 0);
+      if (y == 0)
+        return x != 0;
+    }
+  else
+    {
+      return x >= 0 ? 1 : -1;
+    }
+}
+
+int main(void)
+{
+  if (f(-1, 1) != -1)
+    abort();
+
+  return 0;
+}