This is what I get with your patch and not mine:
neg.w r0 ; 7 neghi2/1
mov.w r0,a0 ; 9
zero_extendhipsi2
add.l a0,r3r1 ; 15
addpsi3/3
Somewhere else, it's getting zero-extended when it should be
sign-extended. That's why I was trying to use ssizetype in c-common.c
Index: expr.c
===================================================================
--- expr.c (revision 140759)
+++ expr.c (working copy)
@@ -8338,14 +8338,18 @@ expand_expr_real_1 (tree exp, rtx target
== TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (subsubexp1, 0))))
&& (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp0, 0)))
== TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (subsubexp1, 0)))))
{
tree op0type = TREE_TYPE (TREE_OPERAND (subsubexp0, 0));
enum machine_mode innermode = TYPE_MODE (op0type);
- bool zextend_p = TYPE_UNSIGNED (op0type);
+ bool zextend_p;
bool sat_p = TYPE_SATURATING (TREE_TYPE (subsubexp0));
+ if (code == POINTER_PLUS_EXPR)
+ zextend_p = false;
+ else
+ zextend_p = TYPE_UNSIGNED (op0type);
if (sat_p == 0)
this_optab = zextend_p ? umadd_widen_optab : smadd_widen_optab;
else
this_optab = zextend_p ? usmadd_widen_optab
: ssmadd_widen_optab;
if (mode == GET_MODE_2XWIDER_MODE (innermode)