Hi,
this is updated patch I am going to commit. As discussed, we also need to match
non-empty CONSTRUCTOR of vectors, but those should never be having CONSTANT
flags
set, so they need care in the other path trhough operand_equal_p, so I will post
separate patch for that.
I updated the comment per Richard's comment and added a testcase. Vuriously
enoug we fold "val? (struct a){} : (struct a){}" only in PRE (tailmerging).
W/o the patch even .optimized dump has the test and we fold it away only after
lowering to RTL:
ret (int val)
{
struct a D.1764;
<bb 2>:
if (val_2(D) != 0)
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
D.1764 = {};
goto <bb 5>;
<bb 4>:
D.1764 = {};
<bb 5>:
return D.1764;
}
ret:
.LFB0:
.cfi_startproc
xorl %eax, %eax
ret
.cfi_endproc
With the patch we get:
ret (int val)
{
struct a D.1764;
<bb 2>:
D.1764 = {};
return D.1764;
}
Honza
* fold-const.c (operand_equal_p): Add code matching empty
constructors.
* gcc.dg/tree-ssa/operand-equal-1.c: Verify that empty constructors
are matched.
Index: fold-const.c
===================================================================
--- fold-const.c (revision 229133)
+++ fold-const.c (working copy)
@@ -2892,6 +2892,11 @@ operand_equal_p (const_tree arg0, const_
return operand_equal_p (TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 0),
flags | OEP_ADDRESS_OF
| OEP_CONSTANT_ADDRESS_OF);
+ case CONSTRUCTOR:
+ /* In GIMPLE empty constructors are allowed in initializers of
+ aggregates. */
+ return (!vec_safe_length (CONSTRUCTOR_ELTS (arg0))
+ && !vec_safe_length (CONSTRUCTOR_ELTS (arg1)));
default:
break;
}
Index: testsuite/gcc.dg/tree-ssa/operand-equal-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0)
+++ testsuite/gcc.dg/tree-ssa/operand-equal-1.c (revision 0)
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre" } */
+struct a {int a,b;};
+struct a ret(int val)
+{
+ return val? (struct a){} : (struct a){};
+}
+/* { dg-final { scan-tree-dump-not "if " "pre"} } */