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; }