Hello, this implements two minor enhancements to code generated by the spu_emit_branch_or_set routine.
This reduces code size for the g++.dg/opt/longbranch1.C to the extent that it once again fits into local store, and thus fixes the failure. Tested on spu-elf. Committed to mainline. Bye, Ulrich ChangeLog: * config/spu/spu.c (spu_emit_branch_or_set): Avoid reverse tests when generating an integer result where possible. Short-cut comparison against 0 also for QImode. Index: gcc/config/spu/spu.c =================================================================== *** gcc/config/spu/spu.c (revision 177794) --- gcc/config/spu/spu.c (working copy) *************** spu_emit_branch_or_set (int is_set, rtx *** 982,987 **** --- 982,1008 ---- } } + /* However, if we generate an integer result, performing a reverse test + would require an extra negation, so avoid that where possible. */ + if (GET_CODE (op1) == CONST_INT && is_set == 1) + { + HOST_WIDE_INT val = INTVAL (op1) + 1; + if (trunc_int_for_mode (val, GET_MODE (op0)) == val) + switch (code) + { + case LE: + op1 = GEN_INT (val); + code = LT; + break; + case LEU: + op1 = GEN_INT (val); + code = LTU; + break; + default: + break; + } + } + comp_mode = SImode; op_mode = GET_MODE (op0); *************** spu_emit_branch_or_set (int is_set, rtx *** 1113,1119 **** if (is_set == 0 && op1 == const0_rtx && (GET_MODE (op0) == SImode ! || GET_MODE (op0) == HImode) && scode == SPU_EQ) { /* Don't need to set a register with the result when we are comparing against zero and branching. */ --- 1134,1141 ---- if (is_set == 0 && op1 == const0_rtx && (GET_MODE (op0) == SImode ! || GET_MODE (op0) == HImode ! || GET_MODE (op0) == QImode) && scode == SPU_EQ) { /* Don't need to set a register with the result when we are comparing against zero and branching. */ -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE ulrich.weig...@de.ibm.com