Home | History | Annotate | Download | only in InstCombine
      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