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