[Bug tree-optimization/79006] New: [6/7 Regression] Invalid transformation in tree-dominators pass
wschmidt at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Jan 5 18:39:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79006
Bug ID: 79006
Summary: [6/7 Regression] Invalid transformation in
tree-dominators pass
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: wschmidt at gcc dot gnu.org
Target Milestone: ---
Compile the following with -Os on GCC 6.3 or current trunk:
typedef struct
{
unsigned long a_type;
union
{
unsigned long a_val;
} a_un;
} Elf64_auxv_t;
void
auxv_up (Elf64_auxv_t *av, unsigned type, unsigned const value)
{
if (av)
for (;; ++av)
{
if (av->a_type == type
|| (av->a_type == 1 && type != 0))
{
av->a_type = type;
av->a_un.a_val = value;
return;
}
}
}
The generated code causes av->a_type to receive a wrong value along the
fall-through path. On powerpc64le, this is what we see:
auxv_up:
cmpdi 0,3,0
beqlr 0
cmpdi 5,4,0
.L6:
ld 9,0(3)
cmpld 7,9,4
bne 7,.L3
.L5:
std 9,0(3) <-- Should be std 4,0(3) to store "type"
std 5,8(3)
blr
.L7:
mr 9,4
b .L5
.L3:
cmpldi 7,9,1
bne 7,.L4
bne 5,.L7
.L4:
addi 3,3,16
b .L6
I've narrowed this down to the dom3 pass. Prior to dom3, the GIMPLE is:
auxv_up (struct Elf64_auxv_t * av, unsigned int type, const unsigned int value)
{
long unsigned int _1;
long unsigned int _2;
long unsigned int _3;
long unsigned int _4;
long unsigned int _5;
long unsigned int _18;
<bb 2> [13.5%]:
if (av_8(D) != 0B)
goto <bb 11>; [73.3%]
else
goto <bb 10>; [26.7%]
<bb 11> [9.9%]:
<bb 3> [100.0%]:
# av_6 = PHI <av_8(D)(11), av_11(9)>
_1 = MEM[base: av_6, offset: 0B];
_2 = (long unsigned int) type_10(D);
if (_1 == _2)
goto <bb 4>; [7.5%]
else
goto <bb 6>; [92.5%]
<bb 4> [7.5%]:
# _3 = PHI <_2(3)>
# av_19 = PHI <av_6(3)>
<bb 5> [9.9%]:
# _18 = PHI <_3(4), _4(8)> ; _18 always equal to _2
# av_15 = PHI <av_19(4), av_16(8)>
av_15->a_type = _18;
_5 = (long unsigned int) value_13(D);
av_15->a_un.a_val = _5;
goto <bb 10>; [100.0%]
<bb 6> [92.5%]:
if (_1 == 1)
goto <bb 7>; [34.0%]
else
goto <bb 9>; [66.0%]
<bb 7> [31.4%]:
if (type_10(D) != 0)
goto <bb 8>; [7.5%]
else
goto <bb 9>; [92.5%]
<bb 8> [2.4%]:
# _4 = PHI <_2(7)>
# av_16 = PHI <av_6(7)>
goto <bb 5>; [100.0%]
<bb 9> [90.1%]:
av_11 = av_6 + 16;
goto <bb 3>; [100.0%]
<bb 10> [13.5%]:
return;
}
Following dom3 we have:
auxv_up (struct Elf64_auxv_t * av, unsigned int type, const unsigned int value)
{
long unsigned int _1;
long unsigned int _2;
long unsigned int _3;
long unsigned int _4;
long unsigned int _5;
long unsigned int _18;
<bb 2> [13.5%]:
if (av_8(D) != 0B)
goto <bb 3>; [73.3%]
else
goto <bb 10>; [26.7%]
<bb 3> [100.0%]:
# av_6 = PHI <av_8(D)(2), av_11(9)>
_1 = MEM[base: av_6, offset: 0B];
_2 = (long unsigned int) type_10(D);
if (_1 == _2)
goto <bb 4>; [7.5%]
else
goto <bb 6>; [92.5%]
<bb 4> [7.5%]:
# _3 = PHI <_2(3)>
# av_19 = PHI <av_6(3)>
<bb 5> [9.9%]:
# _18 = PHI <_1(4), _2(8)> ; _18 can now equal av->a_type instead
# av_15 = PHI <av_6(4), av_6(8)>
av_6->a_type = _18;
_5 = (long unsigned int) value_13(D);
av_6->a_un.a_val = _5;
goto <bb 10>; [100.0%]
<bb 6> [92.5%]:
if (_1 == 1)
goto <bb 7>; [34.0%]
else
goto <bb 9>; [66.0%]
<bb 7> [31.4%]:
if (type_10(D) != 0)
goto <bb 8>; [7.5%]
else
goto <bb 9>; [92.5%]
<bb 8> [2.4%]:
# _4 = PHI <_2(7)>
# av_16 = PHI <av_6(7)>
goto <bb 5>; [100.0%]
<bb 9> [90.1%]:
av_11 = av_6 + 16;
goto <bb 3>; [100.0%]
<bb 10> [13.5%]:
return;
}
More information about the Gcc-bugs
mailing list