Hi, I am working on a GCC port for a 32 bit RISC. I have a doubt regarding the assembly code generated by the ported compiler for the below test case. (----- Snip starts -----) signed char g_scOperand; signed char g_scResult; #define CONSTANT_16_BIT (short) 0x8000 void vMulSignedCharGlobalWith16BitImmediateValue( void ) { g_scResult = g_scOperand * CONSTANT_16_BIT; } (----- Snip ends -----) The result of multiplication is stored in a byte size variable 'g_scResult'. As the LSB value for 'CONSTANT_16_BIT' is zero, the result of multiplication can be optimized to 0. I used -O3 option. The ported compiler generates the following RTL after the Instruction combination pass. (----- Snip starts -----) (insn 5 2 6 2 ../test/test.c:6 (set (reg/f:SI 43) (high:SI (symbol_ref:SI ("g_scOperand") <var_decl 0xb7ce3000 g_scOperand>))) 27 {*load_high_of_splittable_symbol} (nil)) (insn 6 5 8 2 ../test/test.c:6 (set (reg:SI 41) (sign_extend:SI (mem:QI (lo_sum:SI (reg/f:SI 43) (symbol_ref:SI ("g_scOperand") <var_decl 0xb7ce3000 g_scOperand>)) [0 S1 A8]))) 22 {*extendqisi2} (expr_list:REG_DEAD (reg/f:SI 43) (expr_list:REG_EQUAL (sign_extend:SI (mem/c/i:QI (symbol_ref:SI ("g_scOperand") <var_decl 0xb7ce3000 g_scOperand>) [0 g_scOperand+0 S1 A8])) (nil)))) (insn 8 6 9 2 ../test/test.c:6 (set (reg:SI 45) (ashift:SI (reg:SI 41) (const_int 15 [0xf]))) 5 {ashlsi3} (expr_list:REG_DEAD (reg:SI 41) (expr_list:REG_EQUAL (ashift:SI (reg:SI 41) (const_int 15 [0xf])) (nil)))) (insn 9 8 10 2 ../test/test.c:6 (set (reg:SI 46) (neg:SI (reg:SI 45))) 18 {negsi2} (expr_list:REG_DEAD (reg:SI 45) (nil))) (insn 10 9 0 2 ../test/test.c:6 (set (mem/c/i:QI (symbol_ref:SI ("g_scResult") <var_decl 0xb7ce305c g_scResult>) [0 g_scResult+0 S1 A8]) (subreg:QI (reg:SI 46) 3)) 29 {*movqi} (expr_list:REG_DEAD (reg:SI 46) (nil))) (----- Snip ends -----) The multiplication is taking place as follows. 1. Load variable 'g_scOperand' value to register. 2. 0x8000 is power of 2 (2 raised to 15). Hence multiplication is done by left shifting the register content by 15 times. 3. Since 0x8000 is cast to 'signed short' and it should be treated as negative number. So the register content is negated. 4. The byte value of the result is stored to the variable 'g_scResult'. The negation is taking place using the 'negsi2' pattern as shown below. (define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=b") (neg:SI (match_operand:SI 1 "register_operand" " b")))] "" "subu\t%0,$0,%1" ) But, if I remove machine description for 'negsi2', GCC is able to optimize the multiplication operation. GCC uses subtraction pattern for performing the negation. The Instruction combination pass is able to combine all the instructions into one as shown below. (----- Snip starts -----) (insn 11 10 0 2 ../test/test.c:6 (set (mem/c/i:QI (symbol_ref:SI ("g_scResult") <var_decl 0xb7cf805c g_scResult>) [0 g_scResult+0 S1 A8]) (const_int 0 [0x0])) 28 {*movqi} (nil)) (----- Snip ends -----) I am not able to understand why GCC is not optimizing the result of operation to 0 when 'negsi2' is defined. Please help.