1 ; RUN: opt < %s -instcombine -S | FileCheck %s 2 3 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 5 ; CHECK-LABEL: @oppositesign 6 ; CHECK: add nsw i16 %a, %b 7 define i16 @oppositesign(i16 %x, i16 %y) { 8 ; %a is negative, %b is positive 9 %a = or i16 %x, 32768 10 %b = and i16 %y, 32767 11 %c = add i16 %a, %b 12 ret i16 %c 13 } 14 15 define i16 @zero_sign_bit(i16 %a) { 16 ; CHECK-LABEL: @zero_sign_bit( 17 ; CHECK-NEXT: and 18 ; CHECK-NEXT: add nuw 19 ; CHECK-NEXT: ret 20 %1 = and i16 %a, 32767 21 %2 = add i16 %1, 512 22 ret i16 %2 23 } 24 25 define i16 @zero_sign_bit2(i16 %a, i16 %b) { 26 ; CHECK-LABEL: @zero_sign_bit2( 27 ; CHECK-NEXT: and 28 ; CHECK-NEXT: and 29 ; CHECK-NEXT: add nuw 30 ; CHECK-NEXT: ret 31 %1 = and i16 %a, 32767 32 %2 = and i16 %b, 32767 33 %3 = add i16 %1, %2 34 ret i16 %3 35 } 36 37 declare i16 @bounded(i16 %input); 38 declare i32 @__gxx_personality_v0(...); 39 !0 = !{i16 0, i16 32768} ; [0, 32767] 40 !1 = !{i16 0, i16 32769} ; [0, 32768] 41 42 define i16 @add_bounded_values(i16 %a, i16 %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 43 ; CHECK-LABEL: @add_bounded_values( 44 entry: 45 %c = call i16 @bounded(i16 %a), !range !0 46 %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0 47 cont: 48 ; %c and %d are in [0, 32767]. Therefore, %c + %d doesn't unsigned overflow. 49 %e = add i16 %c, %d 50 ; CHECK: add nuw i16 %c, %d 51 ret i16 %e 52 lpad: 53 %0 = landingpad { i8*, i32 } 54 filter [0 x i8*] zeroinitializer 55 ret i16 42 56 } 57 58 define i16 @add_bounded_values_2(i16 %a, i16 %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 59 ; CHECK-LABEL: @add_bounded_values_2( 60 entry: 61 %c = call i16 @bounded(i16 %a), !range !1 62 %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1 63 cont: 64 ; Similar to add_bounded_values, but %c and %d are in [0, 32768]. Therefore, 65 ; %c + %d may unsigned overflow and we cannot add NUW. 66 %e = add i16 %c, %d 67 ; CHECK: add i16 %c, %d 68 ret i16 %e 69 lpad: 70 %0 = landingpad { i8*, i32 } 71 filter [0 x i8*] zeroinitializer 72 ret i16 42 73 } 74 75 ; CHECK-LABEL: @ripple_nsw1 76 ; CHECK: add nsw i16 %a, %b 77 define i16 @ripple_nsw1(i16 %x, i16 %y) { 78 ; %a has at most one bit set 79 %a = and i16 %y, 1 80 81 ; %b has a 0 bit other than the sign bit 82 %b = and i16 %x, 49151 83 84 %c = add i16 %a, %b 85 ret i16 %c 86 } 87 88 ; Like the previous test, but flip %a and %b 89 ; CHECK-LABEL: @ripple_nsw2 90 ; CHECK: add nsw i16 %b, %a 91 define i16 @ripple_nsw2(i16 %x, i16 %y) { 92 %a = and i16 %y, 1 93 %b = and i16 %x, 49151 94 %c = add i16 %b, %a 95 ret i16 %c 96 } 97 98 ; CHECK-LABEL: @ripple_no_nsw1 99 ; CHECK: add i32 %a, %x 100 define i32 @ripple_no_nsw1(i32 %x, i32 %y) { 101 ; We know nothing about %x 102 %a = and i32 %y, 1 103 %b = add i32 %a, %x 104 ret i32 %b 105 } 106 107 ; CHECK-LABEL: @ripple_no_nsw2 108 ; CHECK: add nuw i16 %a, %b 109 define i16 @ripple_no_nsw2(i16 %x, i16 %y) { 110 ; %a has at most one bit set 111 %a = and i16 %y, 1 112 113 ; %b has a 0 bit, but it is the sign bit 114 %b = and i16 %x, 32767 115 116 %c = add i16 %a, %b 117 ret i16 %c 118 } 119