https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104869
Bug ID: 104869 Summary: [12 Regression] Miscompilation of qt5-qtdeclarative Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- Created attachment 52600 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=52600&action=edit qv4codegen.ii.xz As mentioned in https://bugzilla.redhat.com/show_bug.cgi?id=2061194 , qt5-qtdeclarative is miscompiled on powerpc64le-linux with LTO. I've managed to tweak the preprocessed source, so that the bug is visible also without lto, but still it isn't a reduced testcase and one can just watch for the problems in the dumps or assembly. When the attached preprocessed source is compiled with current trunk on powerpc64le-linux with -mcpu=power8 -O2 -fvisibility=hidden -fPIC -fno-exceptions one can see in the dumps in the _ZN3QV48Compiler7Codegen5visitEPN6QQmlJS3AST14BreakStatementE function: optimized dump: ... l = OBJ_TYPE_REF(_75;(struct ControlFlow)flow_192->3B) (flow_192, 0, &D.312010); l$generator_225 = l.generator; if (l$generator_225 != 0B) goto <bb 18>; [5.50%] else goto <bb 19>; [94.50%] <bb 18> [local count: 237749543]: target$index_204 = MEM <int> [(struct Label *)&l + 8B]; l ={v} {CLOBBER(eol)}; goto <bb 22>; [100.00%] ... <bb 22> [local count: 489336362]: # target$linkLabel$generator_168 = PHI <l$generator_225(18), flow_83(21)> # target$index_81 = PHI <target$index_204(18), -1(21)> # target$unwindLevel_73 = PHI <level_193(18), 0(21)> ... <bb 27> [local count: 489336362]: D.312010 ={v} {CLOBBER}; D.312010 ={v} {CLOBBER(eol)}; if (target$linkLabel$generator_168 == 0B) So far good. Before fwprop1 it is: (call_insn 125 124 651 17 (parallel [ (set (reg:TI 3 3) (call (mem:SI (reg:DI 97 ctr) [0 *OBJ_TYPE_REF(_75;flow_192->3B) S4 A8]) (const_int 0 [0]))) (use (const_int 0 [0])) (set (reg:DI 2 2) (unspec:DI [ (const_int 24 [0x18]) ] UNSPEC_TOCSLOT)) (clobber (reg:DI 96 lr)) ]) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 769 {*call_value_indirect_elfv2di} (expr_list:REG_CALL_DECL (nil) (nil)) (expr_list (use (reg:DI 12 12)) (expr_list:DI (use (reg:DI 3 3)) (expr_list:SI (use (reg:DI 4 4)) (expr_list:DI (use (reg:DI 5 5)) (nil)))))) (insn 651 125 652 17 (set (reg:DI 391 [ l ]) (reg:DI 3 3)) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 670 {*movdi_internal64} (nil)) (insn 652 651 127 17 (set (reg:DI 392 [ l+8 ]) (reg:DI 4 4 [+8 ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 670 {*movdi_internal64} (nil)) (insn 127 652 128 17 (set (reg/f:DI 208 [ l$generator ]) (reg:DI 391 [ l ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 670 {*movdi_internal64} (nil)) (insn 128 127 129 17 (set (reg:CC 258) (compare:CC (reg/f:DI 208 [ l$generator ]) (const_int 0 [0]))) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":108:13 786 {*cmpdi_signed} (nil)) (jump_insn 129 128 130 17 (set (pc) (if_then_else (eq (reg:CC 258) (const_int 0 [0])) (label_ref 135) (pc))) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":108:13 868 {*cbranch} (int_list:REG_BR_PROB 1014686028 (nil)) -> 135) ... (note 130 129 131 18 [bb 18] NOTE_INSN_BASIC_BLOCK) (insn 131 130 132 18 (set (reg:SI 171 [ target$index ]) (subreg:SI (reg:DI 392 [ l+8 ]) 0)) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 546 {*movsi_internal1} (nil)) (insn 132 131 653 18 (clobber (reg:DI 391 [ l ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 -1 (nil)) (insn 653 132 6 18 (clobber (reg:DI 392 [ l+8 ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 -1 (nil)) (insn 6 653 135 18 (set (reg/v/f:DI 172 [ target$linkLabel$generator ]) (reg/f:DI 208 [ l$generator ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 670 {*movdi_internal64} (nil)) This still looks good to me. But next comes fwprop1 and turns that into: ... (insn 651 125 652 17 (set (reg:DI 391 [ l ]) (reg:DI 3 3)) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 670 {*movdi_internal64} (expr_list:REG_DEAD (reg:DI 3 3) (nil))) (insn 652 651 128 17 (set (reg:DI 392 [ l+8 ]) (reg:DI 4 4 [+8 ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 670 {*movdi_internal64} (expr_list:REG_DEAD (reg:DI 4 4 [+8 ]) (nil))) (insn 128 652 129 17 (set (reg:CC 258) (compare:CC (reg:DI 391 [ l ]) (const_int 0 [0]))) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":108:13 786 {*cmpdi_signed} (nil)) (jump_insn 129 128 130 17 (set (pc) (if_then_else (eq (reg:CC 258) (const_int 0 [0])) (label_ref 135) (pc))) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":108:13 868 {*cbranch} (expr_list:REG_DEAD (reg:CC 258) (int_list:REG_BR_PROB 1014686028 (nil))) -> 135) # the above part is still fine ... (note 130 129 131 18 [bb 18] NOTE_INSN_BASIC_BLOCK) (insn 131 130 132 18 (set (reg:SI 171 [ target$index ]) (subreg:SI (reg:DI 392 [ l+8 ]) 0)) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 546 {*movsi_internal1} (expr_list:REG_DEAD (reg:DI 392 [ l+8 ]) (nil))) (insn 132 131 653 18 (clobber (reg:DI 391 [ l ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 -1 (expr_list:REG_UNUSED (reg:DI 391 [ l ]) (nil))) (insn 653 132 6 18 (clobber (reg:DI 392 [ l+8 ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 -1 (expr_list:REG_UNUSED (reg:DI 392 [ l+8 ]) (nil))) (insn 6 653 135 18 (set (reg/v/f:DI 172 [ target$linkLabel$generator ]) (reg:DI 391 [ l ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":107:63 670 {*movdi_internal64} (nil)) But this looks wrong to me, clobber on pseudo 391 throws away its value, so using it in insn 6 looks wrong to me. The web dump still has the IMHO incorrect: (note 130 129 131 20 [bb 20] NOTE_INSN_BASIC_BLOCK) (insn 131 130 132 20 (set (reg:SI 171 [ target$index ]) (subreg:SI (reg:DI 392 [ l+8 ]) 0)) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 546 {*movsi_internal1} (expr_list:REG_DEAD (reg:DI 392 [ l+8 ]) (nil))) (insn 132 131 698 20 (clobber (reg:DI 391 [ l ])) "../../include/QtQml/5.15.3/QtQml/private/../../../../../src/qml/compiler/qv4compilercontrolflow_p.h":109:45 -1 (nil)) (insn 698 132 135 20 (set (reg:CC 394) (compare:CC (reg:DI 403 [ l ]) (const_int 0 [0]))) 786 {*cmpdi_signed} (expr_list:REG_DEAD (reg:DI 391 [ l ]) (nil))) (if the clobber wouldn't be there or if fwprop1 didn't forward propagate to the insns after the clobber the regs clobbered in the clobber, it would be fine). Next cprop3 removes that clobber (insn 132), but supposedly something wrong is kept in DF info or where. Because the init_regs pass later on adds: (insn 760 131 761 19 (clobber (reg:DI 403 [ l ])) -1 (nil)) (insn 761 760 698 19 (set (reg:DI 403 [ l ]) (const_int 0 [0])) -1 (nil)) before insn 698. And this remains there until assembly, which contains the suspicious: li 9,0 mr 31,4 cmpdi 4,9,0 ... beq 4,.L7480 Instead of the originally conditional jump (whether target$linkLabel$generator_168 == 0B) it becomes a fancy unconditional jump, because constant 0 is loaded into register 9 and then it is compared against 0, result stored into cr4.