Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
      2 
      3 // rdar://problem/9246208
      4 
      5 // Basic test.
      6 namespace test0 {
      7   struct A {
      8     A();
      9     int x;
     10   };
     11 
     12   typedef A elt;
     13 
     14   // CHECK:    define [[A:%.*]]* @_ZN5test04testEs(i16 signext
     15   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
     16   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
     17   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
     18   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
     19   // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
     20   // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
     21   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
     22   elt *test(short s) {
     23     return new elt[s];
     24   }
     25 }
     26 
     27 // test0 with a nested array.
     28 namespace test1 {
     29   struct A {
     30     A();
     31     int x;
     32   };
     33 
     34   typedef A elt[100];
     35 
     36   // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test14testEs(i16 signext
     37   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
     38   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
     39   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
     40   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
     41   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
     42   // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
     43   // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
     44   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
     45   elt *test(short s) {
     46     return new elt[s];
     47   }
     48 }
     49 
     50 // test1 with an array cookie.
     51 namespace test2 {
     52   struct A {
     53     A();
     54     ~A();
     55     int x;
     56   };
     57 
     58   typedef A elt[100];
     59 
     60   // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test24testEs(i16 signext
     61   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
     62   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
     63   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
     64   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
     65   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
     66   // CHECK-NEXT: [[T4:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[T2]], i32 4)
     67   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T4]], 1
     68   // CHECK-NEXT: [[T6:%.*]] = or i1 [[T1]], [[T5]]
     69   // CHECK-NEXT: [[T7:%.*]] = extractvalue { i32, i1 } [[T4]], 0
     70   // CHECK-NEXT: [[T8:%.*]] = select i1 [[T6]], i32 -1, i32 [[T7]]
     71   // CHECK-NEXT: call i8* @_Znaj(i32 [[T8]])
     72   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
     73   elt *test(short s) {
     74     return new elt[s];
     75   }
     76 }
     77 
     78 // test0 with a 1-byte element.
     79 namespace test4 {
     80   struct A {
     81     A();
     82   };
     83 
     84   typedef A elt;
     85 
     86   // CHECK:    define [[A:%.*]]* @_ZN5test44testEs(i16 signext
     87   // CHECK:      [[N:%.*]] = sext i16 {{%.*}} to i32
     88   // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
     89   // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
     90   // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
     91   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
     92   elt *test(short s) {
     93     return new elt[s];
     94   }
     95 }
     96 
     97 // test4 with no sext required.
     98 namespace test5 {
     99   struct A {
    100     A();
    101   };
    102 
    103   typedef A elt;
    104 
    105   // CHECK:    define [[A:%.*]]* @_ZN5test54testEi(i32
    106   // CHECK:      [[N:%.*]] = load i32, i32*
    107   // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0
    108   // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]]
    109   // CHECK-NEXT: call i8* @_Znaj(i32 [[T1]])
    110   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
    111   elt *test(int s) {
    112     return new elt[s];
    113   }
    114 }
    115 
    116 // test0 with an unsigned size.
    117 namespace test6 {
    118   struct A {
    119     A();
    120     int x;
    121   };
    122 
    123   typedef A elt;
    124 
    125   // CHECK:    define [[A:%.*]]* @_ZN5test64testEt(i16 zeroext
    126   // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
    127   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 4)
    128   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
    129   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
    130   // CHECK-NEXT: [[T3:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
    131   // CHECK-NEXT: call i8* @_Znaj(i32 [[T3]])
    132   // CHECK:      getelementptr inbounds {{.*}}, i32 [[N]]
    133   elt *test(unsigned short s) {
    134     return new elt[s];
    135   }
    136 }
    137 
    138 // test1 with an unsigned size.
    139 namespace test7 {
    140   struct A {
    141     A();
    142     int x;
    143   };
    144 
    145   typedef A elt[100];
    146 
    147   // CHECK:    define [100 x [[A:%.*]]]* @_ZN5test74testEt(i16 zeroext
    148   // CHECK:      [[N:%.*]] = zext i16 {{%.*}} to i32
    149   // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 400)
    150   // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 1
    151   // CHECK-NEXT: [[T2:%.*]] = extractvalue { i32, i1 } [[T0]], 0
    152   // CHECK-NEXT: [[T3:%.*]] = mul i32 [[N]], 100
    153   // CHECK-NEXT: [[T4:%.*]] = select i1 [[T1]], i32 -1, i32 [[T2]]
    154   // CHECK-NEXT: call i8* @_Znaj(i32 [[T4]])
    155   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T3]]
    156   elt *test(unsigned short s) {
    157     return new elt[s];
    158   }
    159 }
    160 
    161 // test0 with a signed type larger than size_t.
    162 namespace test8 {
    163   struct A {
    164     A();
    165     int x;
    166   };
    167 
    168   typedef A elt;
    169 
    170   // CHECK:    define [[A:%.*]]* @_ZN5test84testEx(i64
    171   // CHECK:      [[N:%.*]] = load i64, i64*
    172   // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
    173   // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
    174   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
    175   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
    176   // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
    177   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
    178   // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
    179   // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
    180   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
    181   elt *test(long long s) {
    182     return new elt[s];
    183   }
    184 }
    185 
    186 // test8 with an unsigned type.
    187 namespace test9 {
    188   struct A {
    189     A();
    190     int x;
    191   };
    192 
    193   typedef A elt;
    194 
    195   // CHECK:    define [[A:%.*]]* @_ZN5test94testEy(i64
    196   // CHECK:      [[N:%.*]] = load i64, i64*
    197   // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296
    198   // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32
    199   // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4)
    200   // CHECK-NEXT: [[T3:%.*]] = extractvalue { i32, i1 } [[T2]], 1
    201   // CHECK-NEXT: [[T4:%.*]] = or i1 [[T0]], [[T3]]
    202   // CHECK-NEXT: [[T5:%.*]] = extractvalue { i32, i1 } [[T2]], 0
    203   // CHECK-NEXT: [[T6:%.*]] = select i1 [[T4]], i32 -1, i32 [[T5]]
    204   // CHECK-NEXT: call i8* @_Znaj(i32 [[T6]])
    205   // CHECK:      getelementptr inbounds {{.*}}, i32 [[T1]]
    206   elt *test(unsigned long long s) {
    207     return new elt[s];
    208   }
    209 }
    210