@@ -323,13 +323,14 @@ IR_FOLD(ADD(C_I16, C_I16))
323323IR_FOLD (ADD (C_I32 , C_I32 ))
324324{
325325 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type || (sizeof (void * ) == 4 && IR_OPT_TYPE (opt ) == IR_ADDR ));
326- IR_FOLD_CONST_I (op1_insn -> val .i32 + op2_insn -> val .i32 );
326+ /* Here and below we use "unsigned math" to prevent undefined signed overflow behavior */
327+ IR_FOLD_CONST_I ((int32_t )(op1_insn -> val .u32 + op2_insn -> val .u32 ));
327328}
328329
329330IR_FOLD (ADD (C_I64 , C_I64 ))
330331{
331332 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type || (sizeof (void * ) == 8 && IR_OPT_TYPE (opt ) == IR_ADDR ));
332- IR_FOLD_CONST_I (op1_insn -> val .i64 + op2_insn -> val .i64 );
333+ IR_FOLD_CONST_I (op1_insn -> val .u64 + op2_insn -> val .u64 );
333334}
334335
335336IR_FOLD (ADD (C_DOUBLE , C_DOUBLE ))
@@ -393,13 +394,13 @@ IR_FOLD(SUB(C_I16, C_I16))
393394IR_FOLD (SUB (C_I32 , C_I32 ))
394395{
395396 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type );
396- IR_FOLD_CONST_I (op1_insn -> val .i32 - op2_insn -> val .i32 );
397+ IR_FOLD_CONST_I (( int32_t )( op1_insn -> val .u32 - op2_insn -> val .u32 ) );
397398}
398399
399400IR_FOLD (SUB (C_I64 , C_I64 ))
400401{
401402 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type );
402- IR_FOLD_CONST_I (op1_insn -> val .i64 - op2_insn -> val .i64 );
403+ IR_FOLD_CONST_I (op1_insn -> val .u64 - op2_insn -> val .u64 );
403404}
404405
405406IR_FOLD (SUB (C_DOUBLE , C_DOUBLE ))
@@ -463,13 +464,13 @@ IR_FOLD(MUL(C_I16, C_I16))
463464IR_FOLD (MUL (C_I32 , C_I32 ))
464465{
465466 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type );
466- IR_FOLD_CONST_I (op1_insn -> val .i32 * op2_insn -> val .i32 );
467+ IR_FOLD_CONST_I (( int32_t )( op1_insn -> val .u32 * op2_insn -> val .u32 ) );
467468}
468469
469470IR_FOLD (MUL (C_I64 , C_I64 ))
470471{
471472 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type );
472- IR_FOLD_CONST_I (op1_insn -> val .i64 * op2_insn -> val .i64 );
473+ IR_FOLD_CONST_I (op1_insn -> val .u64 * op2_insn -> val .u64 );
473474}
474475
475476IR_FOLD (MUL (C_DOUBLE , C_DOUBLE ))
@@ -556,7 +557,7 @@ IR_FOLD(NEG(C_I32))
556557IR_FOLD (NEG (C_I64 ))
557558{
558559 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type );
559- IR_FOLD_CONST_I (- op1_insn -> val .i64 );
560+ IR_FOLD_CONST_I (- op1_insn -> val .u64 );
560561}
561562
562563IR_FOLD (NEG (C_DOUBLE ))
@@ -580,7 +581,7 @@ IR_FOLD(ABS(C_I64))
580581 if (op1_insn -> val .i64 >= 0 ) {
581582 IR_FOLD_COPY (op1 );
582583 } else {
583- IR_FOLD_CONST_I (- op1_insn -> val .i64 );
584+ IR_FOLD_CONST_I (- op1_insn -> val .u64 );
584585 }
585586}
586587
@@ -680,7 +681,7 @@ IR_FOLD(MUL_OV(C_I64, C_I64))
680681 int64_t min = - max - 1 ;
681682 int64_t res ;
682683 IR_ASSERT (IR_OPT_TYPE (opt ) == op1_insn -> type );
683- res = op1_insn -> val .i64 * op2_insn -> val .i64 ;
684+ res = op1_insn -> val .u64 * op2_insn -> val .u64 ;
684685 if (op1_insn -> val .i64 != 0 && res / op1_insn -> val .i64 != op2_insn -> val .i64 && res >= min && res <= max ) {
685686 IR_FOLD_NEXT ;
686687 }
@@ -2518,7 +2519,7 @@ IR_FOLD(ADD(ADD, C_I64))
25182519{
25192520 if (IR_IS_CONST_REF (op1_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op2 ].op )) {
25202521 /* (x + c1) + c2 => x + (c1 + c2) */
2521- val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .i64 + op2_insn -> val .i64 ;
2522+ val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .u64 + op2_insn -> val .u64 ;
25222523 op1 = op1_insn -> op1 ;
25232524 op2 = ir_const (ctx , val , IR_OPT_TYPE (opt ));
25242525 IR_FOLD_RESTART ;
@@ -2556,8 +2557,8 @@ IR_FOLD(ADD(SUB, C_I64))
25562557{
25572558 if (IR_IS_CONST_REF (op1_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op2 ].op )) {
25582559 /* (x - c1) + c2 => x + (c2 - c1) */
2559- val .i64 = op2_insn -> val .i64 - ctx -> ir_base [op1_insn -> op2 ].val .i64 ;
2560- if (val .i64 < 0 && val .i64 - 1 < 0 ) {
2560+ val .i64 = op2_insn -> val .u64 - ctx -> ir_base [op1_insn -> op2 ].val .u64 ;
2561+ if (val .i64 < 0 && val .i64 != INT64_MIN ) {
25612562 val .i64 = - val .i64 ;
25622563 opt ++ ; /* ADD -> SUB */
25632564 }
@@ -2566,7 +2567,7 @@ IR_FOLD(ADD(SUB, C_I64))
25662567 IR_FOLD_RESTART ;
25672568 } else if (IR_IS_CONST_REF (op1_insn -> op1 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op1 ].op )) {
25682569 /* (c1 - x) + c2 => (c1 + c2) - x */
2569- val .i64 = ctx -> ir_base [op1_insn -> op1 ].val .i64 + op2_insn -> val .i64 ;
2570+ val .i64 = ctx -> ir_base [op1_insn -> op1 ].val .u64 + op2_insn -> val .u64 ;
25702571 opt ++ ; /* ADD -> SUB */
25712572 op2 = op1_insn -> op2 ;
25722573 op1 = ir_const (ctx , val , IR_OPT_TYPE (opt ));
@@ -2599,8 +2600,8 @@ IR_FOLD(SUB(ADD, C_I64))
25992600{
26002601 if (IR_IS_CONST_REF (op1_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op2 ].op )) {
26012602 /* (x + c1) - c2 => x + (c1 - c2) */
2602- val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .i64 - op2_insn -> val .i64 ;
2603- if (val .i64 < 0 && val .i64 - 1 < 0 ) {
2603+ val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .u64 - op2_insn -> val .u64 ;
2604+ if (val .i64 < 0 && val .i64 != INT64_MIN ) {
26042605 val .i64 = - val .i64 ;
26052606 } else {
26062607 opt -- ; /* SUB -> ADD */
@@ -2635,7 +2636,7 @@ IR_FOLD(SUB(C_I64, ADD))
26352636{
26362637 if (IR_IS_CONST_REF (op2_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op2_insn -> op2 ].op )) {
26372638 /* c1 - (x + c2) => (c1 - c2) - x */
2638- val .i64 = op1_insn -> val .i64 - ctx -> ir_base [op2_insn -> op2 ].val .i64 ;
2639+ val .i64 = op1_insn -> val .u64 - ctx -> ir_base [op2_insn -> op2 ].val .u64 ;
26392640 op2 = op2_insn -> op1 ;
26402641 op1 = ir_const (ctx , val , IR_OPT_TYPE (opt ));
26412642 IR_FOLD_RESTART ;
@@ -2652,7 +2653,7 @@ IR_FOLD(SUB(SUB, C_ADDR))
26522653 if (IR_IS_CONST_REF (op1_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op2 ].op )) {
26532654 /* (x - c1) - c2 => x - (c1 + c2) */
26542655 val .u64 = ctx -> ir_base [op1_insn -> op2 ].val .u64 + op2_insn -> val .u64 ;
2655- if (val .i64 < 0 && val .i64 - 1 < 0 ) {
2656+ if (val .i64 < 0 && val .i64 != INT64_MIN ) {
26562657 val .i64 = - val .i64 ;
26572658 opt -- ; /* SUB -> ADD */
26582659 }
@@ -2676,8 +2677,8 @@ IR_FOLD(SUB(SUB, C_I64))
26762677{
26772678 if (IR_IS_CONST_REF (op1_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op2 ].op )) {
26782679 /* (x - c1) - c2 => x - (c1 + c2) */
2679- val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .i64 + op2_insn -> val .i64 ;
2680- if (val .i64 < 0 && val .i64 - 1 < 0 ) {
2680+ val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .u64 + op2_insn -> val .u64 ;
2681+ if (val .i64 < 0 && val .i64 != INT64_MIN ) {
26812682 val .i64 = - val .i64 ;
26822683 opt -- ; /* SUB -> ADD */
26832684 }
@@ -2686,7 +2687,7 @@ IR_FOLD(SUB(SUB, C_I64))
26862687 IR_FOLD_RESTART ;
26872688 } else if (IR_IS_CONST_REF (op1_insn -> op1 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op1 ].op )) {
26882689 /* (c1 - x) - c2 => (c1 - c2) - x */
2689- val .i64 = ctx -> ir_base [op1_insn -> op1 ].val .i64 - op2_insn -> val .i64 ;
2690+ val .i64 = ctx -> ir_base [op1_insn -> op1 ].val .u64 - op2_insn -> val .u64 ;
26902691 op2 = op1_insn -> op2 ;
26912692 op1 = ir_const (ctx , val , IR_OPT_TYPE (opt ));
26922693 IR_FOLD_RESTART ;
@@ -2709,7 +2710,7 @@ IR_FOLD(SUB(C_ADDR, SUB))
27092710 } else if (IR_IS_CONST_REF (op2_insn -> op1 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op2_insn -> op1 ].op )) {
27102711 /* c1 - (c2 - x) => x + (c1 - c2) */
27112712 val .u64 = op1_insn -> val .u64 - ctx -> ir_base [op2_insn -> op1 ].val .u64 ;
2712- if (val .i64 < 0 && val .i64 - 1 < 0 ) {
2713+ if (val .i64 < 0 && val .i64 != INT64_MIN ) {
27132714 val .i64 = - val .i64 ;
27142715 opt ++ ; /* ADD -> SUB */
27152716 }
@@ -2727,14 +2728,14 @@ IR_FOLD(SUB(C_I64, SUB))
27272728{
27282729 if (IR_IS_CONST_REF (op2_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op2_insn -> op2 ].op )) {
27292730 /* c1 - (x - c2) => (c1 + c2) - x */
2730- val .i64 = op1_insn -> val .i64 + ctx -> ir_base [op2_insn -> op2 ].val .i64 ;
2731+ val .i64 = op1_insn -> val .u64 + ctx -> ir_base [op2_insn -> op2 ].val .u64 ;
27312732 op2 = op2_insn -> op1 ;
27322733 op1 = ir_const (ctx , val , IR_OPT_TYPE (opt ));
27332734 IR_FOLD_RESTART ;
27342735 } else if (IR_IS_CONST_REF (op2_insn -> op1 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op2_insn -> op1 ].op )) {
27352736 /* c1 - (c2 - x) => x + (c1 - c2) */
2736- val .i64 = op1_insn -> val .i64 - ctx -> ir_base [op2_insn -> op1 ].val .i64 ;
2737- if (val .i64 < 0 && val .i64 - 1 < 0 ) {
2737+ val .i64 = op1_insn -> val .u64 - ctx -> ir_base [op2_insn -> op1 ].val .u64 ;
2738+ if (val .i64 < 0 && val .i64 != INT64_MIN ) {
27382739 val .i64 = - val .i64 ;
27392740 opt ++ ; /* ADD -> SUB */
27402741 }
@@ -2768,7 +2769,7 @@ IR_FOLD(MUL(MUL, C_I64))
27682769{
27692770 if (IR_IS_CONST_REF (op1_insn -> op2 ) && !IR_IS_SYM_CONST (ctx -> ir_base [op1_insn -> op2 ].op )) {
27702771 /* (x * c1) * c2 => x * (c1 * c2) */
2771- val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .i64 * op2_insn -> val .i64 ;
2772+ val .i64 = ctx -> ir_base [op1_insn -> op2 ].val .u64 * op2_insn -> val .u64 ;
27722773 op1 = op1_insn -> op1 ;
27732774 op2 = ir_const (ctx , val , IR_OPT_TYPE (opt ));
27742775 IR_FOLD_RESTART ;
0 commit comments