[Bug rtl-optimization/54342] New: [4.8 Regression] Wrong mode of call argument
vbyakovl23 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Tue Aug 21 11:04:00 GMT 2012
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54342
Bug #: 54342
Summary: [4.8 Regression] Wrong mode of call argument
Classification: Unclassified
Product: gcc
Version: 4.8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: rtl-optimization
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: vbyakovl23@gmail.com
The argument of call has mode OI rather than V8SF. Test case
-------------------------------------------------
#include <immintrin.h>
typedef union un1
{
__m256 x;
float f;
} UN1;
UN1 u;
extern __m256 y;
extern int bar2(UN1);
int foo2 ()
{
u.x = y;
return bar2(u);
}
----------------------------------------------
Dump after expand
(note 4 2 5 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
(insn 5 4 6 3 (set (reg/f:DI 62)
(symbol_ref:DI ("u") <var_decl 0x7f312f270a00 u>)) er.c:13 -1
(nil))
(insn 6 5 7 3 (set (reg:V8SF 63)
(mem/c:V8SF (symbol_ref:DI ("y") [flags 0x40] <var_decl 0x7f312f270aa0
y>) [2 y+0 S32 A256])) er.c:13 -1
(nil))
(insn 7 6 8 3 (set (mem/c:V8SF (reg/f:DI 62) [0 u.x+0 S32 A256])
(reg:V8SF 63)) er.c:13 -1
(nil))
(insn 8 7 9 3 (set (reg/f:DI 65)
(symbol_ref:DI ("u") <var_decl 0x7f312f270a00 u>)) er.c:14 -1
(nil))
(insn 9 8 10 3 (set (reg:OI 64)
(mem/c:OI (reg/f:DI 65) [3 u+0 S32 A256])) er.c:14 -1
(nil))
(insn 10 9 11 3 (set (reg:OI 21 xmm0)
(reg:OI 64)) er.c:14 -1
(nil))
(call_insn/j 11 10 12 3 (parallel [
(set (reg:SI 0 ax)
(call (mem:QI (symbol_ref:DI ("bar2") [flags 0x41]
<function_decl 0x7f312f27b300 bar2>) [0 bar2 S1 A8])
(const_int 0 [0])))
(unspec [
(const_int 1 [0x1])
] UNSPEC_CALL_NEEDS_VZEROUPPER)
]) er.c:14 -1
(nil)
(expr_list:REG_DEP_TRUE (use (reg:OI 21 xmm0))
(nil)))
Following patch fixes that.
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 53554a9..bb39e7f 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -1639,7 +1639,8 @@ compute_record_mode (tree type)
/* If we only have one real field; use its mode if that mode's size
matches the type's size. This only applies to RECORD_TYPE. This
does not apply to unions. */
- if (TREE_CODE (type) == RECORD_TYPE && mode != VOIDmode
+ if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)
+ && mode != VOIDmode
&& host_integerp (TYPE_SIZE (type), 1)
&& GET_MODE_BITSIZE (mode) == TREE_INT_CST_LOW (TYPE_SIZE (type)))
SET_TYPE_MODE (type, mode);
More information about the Gcc-bugs
mailing list