Hi, I try to add cbranchhi4 and cbranchsi4 to a new machine description for a 16 bit target. I have no problem with cbranchhi4. But cbranchsi4 does not work in other optimization modes than O0. Here is the code I include to implement cbranchsi4: _____________________target.md_____________________________________ (define_expand "cbranchsi4" [(set (pc) (if_then_else (match_operator 0 "any_comparison_operator" [(match_operand:SI 1 "nonimmediate_operand" "") (match_operand:SI 2 "general_operand" "")]) (label_ref (match_operand 3 "" "")) (pc)))] "" { tam16_expand_cbranchsi4(operands); DONE; }) __________________________________________________________________ _____________________target.c_______________________________________ void tam16_expand_cbranchsi4 (rtx ops[]) { enum rtx_code code = GET_CODE (ops[0]); enum rtx_code code1 = EQ; enum rtx_code code2 = EQ; enum rtx_code code3 = EQ; rtx op1lo = simplify_gen_subreg(HImode,ops[1],SImode,0); rtx op2lo = simplify_gen_subreg(HImode,ops[2],SImode,0); rtx op1hi = simplify_gen_subreg(HImode,ops[1],SImode,2); rtx op2hi = simplify_gen_subreg(HImode,ops[2],SImode,2); rtx branch1 = NULL; rtx branch2 = NULL; rtx branch3 = NULL; rtx condition1 = NULL; rtx condition2 = NULL; rtx condition3 = NULL; rtx nojump_label = gen_label_rtx (); rtx jump_label = ops[3]; printf ("[ ops ]\n"); debug_rtx (ops[0]); debug_rtx (ops[1]); debug_rtx (ops[2]); debug_rtx (ops[3]); switch (code) { default: gcc_unreachable (); break; case EQ: code1 = NE; branch1 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = EQ; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case NE: code1 = NE; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code3 = NE; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case LT: code1 = LT; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = NE; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = LTU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case LE: code1 = LT; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = GT; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = LEU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case GT: code1 = GT; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = NE; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = GTU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case GE: code1 = GT; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = LT; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = GEU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case LTU: code1 = LTU; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = NE; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = LTU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case LEU: code1 = LTU; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = GTU; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = LEU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case GTU: code1 = GTU; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = NE; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = GTU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; case GEU: code1 = GTU; branch1 = gen_rtx_LABEL_REF (VOIDmode, jump_label); code2 = LTU; branch2 = gen_rtx_LABEL_REF (VOIDmode, nojump_label); code3 = GEU; branch3 = gen_rtx_LABEL_REF (VOIDmode, jump_label); break; } // Compute the condition rtxs condition1 = gen_rtx_fmt_ee (code1, VOIDmode, cc0_rtx, const0_rtx); condition2 = gen_rtx_fmt_ee (code2, VOIDmode, cc0_rtx, const0_rtx); condition3 = gen_rtx_fmt_ee (code3, VOIDmode, cc0_rtx, const0_rtx); gcc_assert (condition1 != NULL); gcc_assert (condition2 != NULL); gcc_assert (condition3 != NULL); gcc_assert (op1lo != NULL); gcc_assert (op1lo != NULL); gcc_assert (op2hi != NULL); gcc_assert (op2hi != NULL); // Compare MSB emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, gen_rtx_COMPARE (HImode, op1hi, op2hi))); // Branch 1 if (branch1 != NULL) { emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, condition1, branch1, pc_rtx))); } // Branch 2 if (branch2 != NULL) { emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, condition2, branch2, pc_rtx))); } // Compare LSB emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, gen_rtx_COMPARE (HImode, op1lo, op2lo))); // Branch 3 if (branch3 != NULL) { emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode, condition3, branch3, pc_rtx))); } // No jump, continue here ... emit_label (nojump_label); } __________________________________________________________________ And here is the result of the compilation of a program with long (SImode) comparisons with -O1: $ /home/guest1/tam16/libexec/gcc/tam16/4.3.3/cc1 -quiet main.c -quiet -dumpbase main.c -auxbase main -O1 -o main.s [ ops ] (ge:SI (reg:SI 17 [ aa.1 ]) (reg:SI 16 [ bb.2 ])) (reg:SI 17 [ aa.1 ]) (reg:SI 16 [ bb.2 ]) (code_label 0 0 0 3 "" [0 uses]) main.c: In function ‘main’: main.c:283: internal compiler error: Segmentation fault Please submit a full bug report, with preprocessed source if appropriate. After debugging with GDB, I found out that equiv_constant is called with a null rtx as argument: Program received signal SIGSEGV, Segmentation fault. equiv_constant (x=0x0) at ../../gcc-4.3.3/gcc/cse.c:3603 3603 if (REG_P (x) (gdb) bt #0 equiv_constant (x=0x0) at ../../gcc-4.3.3/gcc/cse.c:3603 #1 0x0836bf37 in fold_rtx (x=0xb7c35c30, insn=0xb7c3baa0) at ../../gcc-4.3.3/gcc/cse.c:3056 #2 0x0836c1b5 in fold_rtx (x=0xb7c36de0, insn=0xb7c3baa0) at ../../gcc-4.3.3/gcc/cse.c:3055 #3 0x0836ee14 in cse_insn (insn=0xb7c3baa0, libcall_insn=0x0) at ../../gcc-4.3.3/gcc/cse.c:4294 #4 0x0837256b in cse_main (f=0xb7c9f780, nregs=25) at ../../gcc-4.3.3/gcc/cse.c:6093 #5 0x08372daa in rest_of_handle_cse () at ../../gcc-4.3.3/gcc/cse.c:7022 #6 0x081a25e4 in execute_one_pass (pass=0x8499cc0) at ../../gcc-4.3.3/gcc/passes.c:1122 #7 0x081a2787 in execute_pass_list (pass=0x8499cc0) at ../../gcc-4.3.3/gcc/passes.c:1176 #8 0x081a279a in execute_pass_list (pass=0x8497400) at ../../gcc-4.3.3/gcc/passes.c:1177 #9 0x08238369 in tree_rest_of_compilation (fndecl=0xb7c9bb60) at ../../gcc-4.3.3/gcc/tree-optimize.c:404 #10 0x0831b698 in cgraph_expand_function (node=0xb7c37380) at ../../gcc-4.3.3/gcc/cgraphunit.c:1166 #11 0x0831cffd in cgraph_optimize () at ../../gcc-4.3.3/gcc/cgraphunit.c:1229 #12 0x08057947 in c_write_global_declarations () at ../../gcc-4.3.3/gcc/c-decl.c:8086 #13 0x082041d7 in toplev_main (argc=11, argv=0xbfabc324) at ../../gcc-4.3.3/gcc/toplev.c:1055 #14 0x080a4792 in main (argc=Cannot access memory at address 0x5 ) at ../../gcc-4.3.3/gcc/main.c:35 Obviously, my method to implement cbranchsi4 is wrong. Please, I need advice to have it well done. Regards, Florent.