re PR target/47312 (ICE: in expand_ternary_op, at optabs.c:656 with -flto -mno-sse...
authorJakub Jelinek <jakub@redhat.com>
Thu, 3 Feb 2011 10:53:19 +0000 (11:53 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 3 Feb 2011 10:53:19 +0000 (11:53 +0100)
PR target/47312
* expr.c (expand_expr_real_2) <case FMA_EXPR>: If target doesn't expand
fma, expand FMA_EXPR as fma{,f,l} call.

* gcc.target/i386/pr47312.c: New test.

From-SVN: r169786

gcc/ChangeLog
gcc/expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr47312.c [new file with mode: 0644]

index cffaf02baf20ab33decb0916d01d7b855e8a7522..1588c6f00d7211ff6a996e1509010bf8a6cbf69b 100644 (file)
@@ -1,5 +1,9 @@
 2011-02-03  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/47312
+       * expr.c (expand_expr_real_2) <case FMA_EXPR>: If target doesn't expand
+       fma, expand FMA_EXPR as fma{,f,l} call.
+
        PR lto/47274
        * lto-streamer-out.c (write_symbol): When writing kind and visibility,
        copy them into a unsigned char variable and pass address of it to
index e6b42795b3a1b8c02733cfbd00e8f6867f4c6951..df15c928bee800edbd0c126c4cda5025f68c80f8 100644 (file)
@@ -7695,6 +7695,18 @@ expand_expr_real_2 (sepops ops, rtx target, enum machine_mode tmode,
        optab opt = fma_optab;
        gimple def0, def2;
 
+       /* If there is no insn for FMA, emit it as __builtin_fma{,f,l}
+          call.  */
+       if (optab_handler (fma_optab, mode) == CODE_FOR_nothing)
+         {
+           tree fn = mathfn_built_in (TREE_TYPE (treeop0), BUILT_IN_FMA);
+           tree call_expr;
+
+           gcc_assert (fn != NULL_TREE);
+           call_expr = build_call_expr (fn, 3, treeop0, treeop1, treeop2);
+           return expand_builtin (call_expr, target, subtarget, mode, false);
+         }
+
        def0 = get_def_for_expr (treeop0, NEGATE_EXPR);
        def2 = get_def_for_expr (treeop2, NEGATE_EXPR);
 
index 001d60425bb697c5bbc4f20d8fbbfaea90d0c330..3ea0a1b585f51f58137e76764698f10911297d12 100644 (file)
@@ -1,5 +1,8 @@
 2011-02-03  Jakub Jelinek  <jakub@redhat.com>
 
+       PR target/47312
+       * gcc.target/i386/pr47312.c: New test.
+
        PR target/47564
        * gcc.target/i386/pr47564.c: New test.
 
diff --git a/gcc/testsuite/gcc.target/i386/pr47312.c b/gcc/testsuite/gcc.target/i386/pr47312.c
new file mode 100644 (file)
index 0000000..a63089d
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR target/47312 */
+/* { dg-do link } */
+/* { dg-require-effective-target lto } */
+/* { dg-require-effective-target xop } */
+/* { dg-options "-O -flto -mno-sse3 -mxop" } */
+
+extern double fma (double, double, double);
+extern float fmaf (float, float, float);
+extern long double fmal (long double, long double, long double);
+
+volatile float f;
+volatile double d;
+volatile long double ld;
+
+int
+main ()
+{
+  f = fmaf (f, f, f);
+  d = fma (d, d, d);
+  ld = fmal (ld, ld, ld);
+  asm volatile ("" : : "r" (&f), "r" (&d), "r" (&ld) : "memory");
+  return 0;
+}