1; RUN: opt < %s -instcombine -S | FileCheck %s 2 3target 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 7define 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 15define 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 25define 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 37declare i16 @bounded(i16 %input); 38declare i32 @__gxx_personality_v0(...); 39!0 = !{i16 0, i16 32768} ; [0, 32767] 40!1 = !{i16 0, i16 32769} ; [0, 32768] 41 42define i16 @add_bounded_values(i16 %a, i16 %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 43; CHECK-LABEL: @add_bounded_values( 44entry: 45 %c = call i16 @bounded(i16 %a), !range !0 46 %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !0 47cont: 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 52lpad: 53 %0 = landingpad { i8*, i32 } 54 filter [0 x i8*] zeroinitializer 55 ret i16 42 56} 57 58define 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( 60entry: 61 %c = call i16 @bounded(i16 %a), !range !1 62 %d = invoke i16 @bounded(i16 %b) to label %cont unwind label %lpad, !range !1 63cont: 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 69lpad: 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 77define 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 91define 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 100define 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 109define 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