Home | History | Annotate | Download | only in CodeGen
      1 // Check -fsanitize=signed-integer-overflow and
      2 // -fsanitize=unsigned-integer-overflow with promoted unsigned types
      3 //
      4 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
      5 // RUN:   -fsanitize=signed-integer-overflow | FileCheck %s --check-prefix=CHECKS
      6 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s \
      7 // RUN:   -fsanitize=unsigned-integer-overflow | FileCheck %s --check-prefix=CHECKU
      8 
      9 unsigned short si, sj, sk;
     10 unsigned char ci, cj, ck;
     11 
     12 extern void opaqueshort(unsigned short);
     13 extern void opaquechar(unsigned char);
     14 
     15 // CHECKS-LABEL:   define void @testshortadd()
     16 // CHECKU-LABEL: define void @testshortadd()
     17 void testshortadd() {
     18   // CHECKS:        load i16, i16* @sj
     19   // CHECKS:        load i16, i16* @sk
     20   // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
     21   // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
     22   // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
     23   // CHECKS:        call void @__ubsan_handle_add_overflow
     24   //
     25   // CHECKU:      [[T1:%.*]] = load i16, i16* @sj
     26   // CHECKU:      [[T2:%.*]] = zext i16 [[T1]]
     27   // CHECKU:      [[T3:%.*]] = load i16, i16* @sk
     28   // CHECKU:      [[T4:%.*]] = zext i16 [[T3]]
     29   // CHECKU-NOT:  llvm.sadd
     30   // CHECKU-NOT:  llvm.uadd
     31   // CHECKU:      [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
     32 
     33   si = sj + sk;
     34 }
     35 
     36 // CHECKS-LABEL:   define void @testshortsub()
     37 // CHECKU-LABEL: define void @testshortsub()
     38 void testshortsub() {
     39 
     40   // CHECKS:        load i16, i16* @sj
     41   // CHECKS:        load i16, i16* @sk
     42   // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
     43   // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
     44   // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
     45   // CHECKS:        call void @__ubsan_handle_sub_overflow
     46   //
     47   // CHECKU:      [[T1:%.*]] = load i16, i16* @sj
     48   // CHECKU:      [[T2:%.*]] = zext i16 [[T1]]
     49   // CHECKU:      [[T3:%.*]] = load i16, i16* @sk
     50   // CHECKU:      [[T4:%.*]] = zext i16 [[T3]]
     51   // CHECKU-NOT:  llvm.ssub
     52   // CHECKU-NOT:  llvm.usub
     53   // CHECKU:      [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
     54 
     55   si = sj - sk;
     56 }
     57 
     58 // CHECKS-LABEL:   define void @testshortmul()
     59 // CHECKU-LABEL: define void @testshortmul()
     60 void testshortmul() {
     61 
     62   // CHECKS:        load i16, i16* @sj
     63   // CHECKS:        load i16, i16* @sk
     64   // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
     65   // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
     66   // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
     67   // CHECKS:        call void @__ubsan_handle_mul_overflow
     68   //
     69   // CHECKU:      [[T1:%.*]] = load i16, i16* @sj
     70   // CHECKU:      [[T2:%.*]] = zext i16 [[T1]]
     71   // CHECKU:      [[T3:%.*]] = load i16, i16* @sk
     72   // CHECKU:      [[T4:%.*]] = zext i16 [[T3]]
     73   // CHECKU-NOT:  llvm.smul
     74   // CHECKU-NOT:  llvm.umul
     75   // CHECKU:      [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
     76   si = sj * sk;
     77 }
     78 
     79 // CHECKS-LABEL:   define void @testcharadd()
     80 // CHECKU-LABEL: define void @testcharadd()
     81 void testcharadd() {
     82 
     83   // CHECKS:        load i8, i8* @cj
     84   // CHECKS:        load i8, i8* @ck
     85   // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
     86   // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
     87   // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
     88   // CHECKS:        call void @__ubsan_handle_add_overflow
     89   //
     90   // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
     91   // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
     92   // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
     93   // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
     94   // CHECKU-NOT:  llvm.sadd
     95   // CHECKU-NOT:  llvm.uadd
     96   // CHECKU:      [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
     97 
     98   ci = cj + ck;
     99 }
    100 
    101 // CHECKS-LABEL:   define void @testcharsub()
    102 // CHECKU-LABEL: define void @testcharsub()
    103 void testcharsub() {
    104 
    105   // CHECKS:        load i8, i8* @cj
    106   // CHECKS:        load i8, i8* @ck
    107   // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
    108   // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
    109   // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
    110   // CHECKS:        call void @__ubsan_handle_sub_overflow
    111   //
    112   // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
    113   // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
    114   // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
    115   // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
    116   // CHECKU-NOT:  llvm.ssub
    117   // CHECKU-NOT:  llvm.usub
    118   // CHECKU:      [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
    119 
    120   ci = cj - ck;
    121 }
    122 
    123 // CHECKS-LABEL:   define void @testcharmul()
    124 // CHECKU-LABEL: define void @testcharmul()
    125 void testcharmul() {
    126 
    127   // CHECKS:        load i8, i8* @cj
    128   // CHECKS:        load i8, i8* @ck
    129   // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
    130   // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
    131   // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
    132   // CHECKS:        call void @__ubsan_handle_mul_overflow
    133   //
    134   // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
    135   // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
    136   // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
    137   // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
    138   // CHECKU-NOT:  llvm.smul
    139   // CHECKU-NOT:  llvm.umul
    140   // CHECKU:      [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
    141 
    142   ci = cj * ck;
    143 }
    144