brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.4 KiB · 7ede07a Raw
367 lines · cpp
1// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++98 -o - | FileCheck %s2// RUN: %clang_cc1 -Wno-unused-value -triple %itanium_abi_triple -emit-llvm %s -std=c++11 -o - | FileCheck -check-prefix=CHECK -check-prefix=CHECK11 %s3 4// CHECK: @i = {{(dso_local )?}}global [[INT:i[0-9]+]] 05volatile int i, j, k;6volatile int ar[5];7volatile char c;8// CHECK: @ci = {{(dso_local )?}}global [[CINT:.*]] zeroinitializer9volatile _Complex int ci;10volatile struct S {11#ifdef __cplusplus12  void operator =(volatile struct S&o) volatile;13#endif14  int i;15} a, b;16 17//void operator =(volatile struct S&o1, volatile struct S&o2) volatile;18int printf(const char *, ...);19 20 21// CHECK: define {{.*}}void @{{.*}}test22void test() {23 24  asm("nop"); // CHECK: call void asm25 26  // should not load in C++9827  i;28  // CHECK11-NEXT: load volatile [[INT]], ptr @i29 30  (float)(ci);31  // CHECK-NEXT: load volatile [[INT]], ptr @ci32  // CHECK-NEXT: load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)33  // CHECK-NEXT: sitofp [[INT]]34 35  // These are not uses in C++98:36  //   [expr.static.cast]p6:37  //     The lvalue-to-rvalue . . . conversions are not applied to the expression.38  (void)ci;39  // CHECK11-NEXT: load volatile [[INT]], ptr @ci40  // CHECK11-NEXT: load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)41 42  (void)a;43 44  (void)(ci=ci);45  // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]], ptr @ci46  // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)47  // CHECK-NEXT: store volatile [[INT]] [[R]], ptr @ci48  // CHECK-NEXT: store volatile [[INT]] [[I]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)49 50  (void)(i=j);51  // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], ptr @j52  // CHECK-NEXT: store volatile [[INT]] [[T]], ptr @i53 54  ci+=ci;55  // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], ptr @ci56  // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)57  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], ptr @ci58  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)59  // Not sure why they're ordered this way.60  // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]61  // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]62  // CHECK-NEXT: store volatile [[INT]] [[R]], ptr @ci63  // CHECK-NEXT: store volatile [[INT]] [[I]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)64 65  // Note that C++ requires an extra load volatile over C from the LHS of the '+'.66  (ci += ci) + ci;67  // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], ptr @ci68  // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)69  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], ptr @ci70  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)71  // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]]72  // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]]73  // CHECK-NEXT: store volatile [[INT]] [[R]], ptr @ci74  // CHECK-NEXT: store volatile [[INT]] [[I]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)75  // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], ptr @ci76  // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)77  // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], ptr @ci78  // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)79  // These additions can be elided.80  // CHECK-NEXT: add [[INT]] [[R1]], [[R2]]81  // CHECK-NEXT: add [[INT]] [[I1]], [[I2]]82 83  asm("nop"); // CHECK-NEXT: call void asm84 85  // Extra load volatile in C++.86  (i += j) + k;87  // CHECK-NEXT: load volatile88  // CHECK-NEXT: load volatile89  // CHECK-NEXT: add nsw [[INT]]90  // CHECK-NEXT: store volatile91  // CHECK-NEXT: load volatile92  // CHECK-NEXT: load volatile93  // CHECK-NEXT: add nsw [[INT]]94 95  asm("nop"); // CHECK-NEXT: call void asm96 97  // Extra load volatile in C++.98  (i += j) + 1;99  // CHECK-NEXT: load volatile100  // CHECK-NEXT: load volatile101  // CHECK-NEXT: add nsw [[INT]]102  // CHECK-NEXT: store volatile103  // CHECK-NEXT: load volatile104  // CHECK-NEXT: add nsw [[INT]]105 106  asm("nop"); // CHECK-NEXT: call void asm107 108  ci+ci;109  // CHECK-NEXT: load volatile110  // CHECK-NEXT: load volatile111  // CHECK-NEXT: load volatile112  // CHECK-NEXT: load volatile113  // CHECK-NEXT: add [[INT]]114  // CHECK-NEXT: add [[INT]]115 116  __real i;117 118  +ci;119  // CHECK-NEXT: load volatile120  // CHECK-NEXT: load volatile121 122  asm("nop"); // CHECK-NEXT: call void asm123 124  (void)(i=i);125  // CHECK-NEXT: load volatile126  // CHECK-NEXT: store volatile127 128  (float)(i=i);129  // CHECK-NEXT: load volatile130  // CHECK-NEXT: store volatile131  // CHECK-NEXT: load volatile132  // CHECK-NEXT: sitofp133 134  (void)i; // This is now a load in C++11135  // CHECK11-NEXT: load volatile136 137  i=i;138  // CHECK-NEXT: load volatile139  // CHECK-NEXT: store volatile140 141  // Extra load volatile in C++.142  i=i=i;143  // CHECK-NEXT: load volatile144  // CHECK-NEXT: store volatile145  // CHECK-NEXT: load volatile146  // CHECK-NEXT: store volatile147 148  (void)__builtin_choose_expr(0, i=i, j=j);149  // CHECK-NEXT: load volatile150  // CHECK-NEXT: store volatile151 152  k ? (i=i) : (j=j);153  // CHECK-NEXT: load volatile154  // CHECK-NEXT: icmp155  // CHECK-NEXT: br i1156  // CHECK: load volatile157  // CHECK-NEXT: store volatile158  // CHECK-NEXT: br label159  // CHECK: load volatile160  // CHECK-NEXT: store volatile161  // CHECK-NEXT: br label162  // CHECK:      phi163 164  (void)(i,(i=i)); // first i is also a load in C++11165  // CHECK11-NEXT: load volatile166  // CHECK-NEXT: load volatile167  // CHECK-NEXT: store volatile168 169  i=i,k; // k is also a load in C++11170  // CHECK-NEXT: load volatile [[INT]], ptr @i171  // CHECK-NEXT: store volatile {{.*}}, ptr @i172  // CHECK11-NEXT: load volatile [[INT]], ptr @k173 174  (i=j,k=j);175  // CHECK-NEXT: load volatile [[INT]], ptr @j176  // CHECK-NEXT: store volatile {{.*}}, ptr @i177  // CHECK-NEXT: load volatile [[INT]], ptr @j178  // CHECK-NEXT: store volatile {{.*}}, ptr @k179 180  (i=j,k); // k is also a load in C++11181  // CHECK-NEXT: load volatile [[INT]], ptr @j182  // CHECK-NEXT: store volatile {{.*}}, ptr @i183  // CHECK11-NEXT: load volatile [[INT]], ptr @k184 185  (i,j); // i and j both are loads in C++11186  // CHECK11-NEXT: load volatile [[INT]], ptr @i187  // CHECK11-NEXT: load volatile [[INT]], ptr @j188 189  // Extra load in C++.190  i=c=k;191  // CHECK-NEXT: load volatile192  // CHECK-NEXT: trunc193  // CHECK-NEXT: store volatile194  // CHECK-NEXT: load volatile195  // CHECK-NEXT: sext196  // CHECK-NEXT: store volatile197 198  i+=k;199  // CHECK-NEXT: load volatile200  // CHECK-NEXT: load volatile201  // CHECK-NEXT: add nsw [[INT]]202  // CHECK-NEXT: store volatile203 204  ci; // ci is a load in C++11205  // CHECK11-NEXT: load volatile {{.*}} @ci206  // CHECK11-NEXT: load volatile {{.*}} @ci, i32 0, i32 1207 208  asm("nop"); // CHECK-NEXT: call void asm209 210  (int)ci;211  // CHECK-NEXT: load volatile {{.*}} @ci212  // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1213 214  (bool)ci;215  // CHECK-NEXT: load volatile {{.*}} @ci216  // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1217  // CHECK-NEXT: icmp ne218  // CHECK-NEXT: icmp ne219  // CHECK-NEXT: or i1220 221  ci=ci;222  // CHECK-NEXT: load volatile223  // CHECK-NEXT: load volatile224  // CHECK-NEXT: store volatile225  // CHECK-NEXT: store volatile226 227  asm("nop"); // CHECK-NEXT: call void asm228 229  // Extra load in C++.230  ci=ci=ci;231  // CHECK-NEXT: load volatile232  // CHECK-NEXT: load volatile233  // CHECK-NEXT: store volatile234  // CHECK-NEXT: store volatile235  // CHECK-NEXT: load volatile236  // CHECK-NEXT: load volatile237  // CHECK-NEXT: store volatile238  // CHECK-NEXT: store volatile239 240  __imag ci = __imag ci = __imag ci;241  // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)242  // CHECK-NEXT: store volatile [[INT]] [[T]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)243  // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)244  // CHECK-NEXT: store volatile [[INT]] [[T]], ptr getelementptr inbounds nuw ([[CINT]], ptr @ci, i32 0, i32 1)245 246  __real (i = j);247  // CHECK-NEXT: load volatile248  // CHECK-NEXT: store volatile249 250  __imag i;251  252  // ============================================================253  // FIXME: Test cases we get wrong.254 255  // A use.  We load all of a into a copy of a, then load i.  gcc forgets to do256  // the assignment.257  // (a = a).i;258 259  // ============================================================260  // Test cases where we intentionally differ from gcc, due to suspected bugs in261  // gcc.262 263  // Not a use.  gcc forgets to do the assignment.264  // CHECK-NEXT: call {{.*}}void265  ((a=a),a);266 267  // Not a use.  gcc gets this wrong, it doesn't emit the copy!  268  // CHECK-NEXT: call {{.*}}void269  (void)(a=a);270 271  // Not a use.  gcc got this wrong in 4.2 and omitted the side effects272  // entirely, but it is fixed in 4.4.0.273  __imag (i = j);274  // CHECK-NEXT: load volatile275  // CHECK-NEXT: store volatile276 277  // C++ does an extra load here.  Note that we have to do full loads.278  (float)(ci=ci);279  // CHECK-NEXT: load volatile280  // CHECK-NEXT: load volatile281  // CHECK-NEXT: store volatile282  // CHECK-NEXT: store volatile283  // CHECK-NEXT: load volatile284  // CHECK-NEXT: load volatile285  // CHECK-NEXT: sitofp286 287  // Not a use, bug?  gcc treats this as not a use, that's probably a288  // bug due to tree folding ignoring volatile.289  (int)(ci=ci);290  // CHECK-NEXT: load volatile291  // CHECK-NEXT: load volatile292  // CHECK-NEXT: store volatile293  // CHECK-NEXT: store volatile294  // CHECK-NEXT: load volatile295  // CHECK-NEXT: load volatile296 297  // A use.298  (float)(i=i);299  // CHECK-NEXT: load volatile300  // CHECK-NEXT: store volatile301  // CHECK-NEXT: load volatile302  // CHECK-NEXT: sitofp303 304  // A use.  gcc treats this as not a use, that's probably a bug due to tree305  // folding ignoring volatile.306  (int)(i=i);307  // CHECK-NEXT: load volatile308  // CHECK-NEXT: store volatile309  // CHECK-NEXT: load volatile310 311  // A use.312  -(i=j);313  // CHECK-NEXT: load volatile314  // CHECK-NEXT: store volatile315  // CHECK-NEXT: load volatile316  // CHECK-NEXT: sub317 318  // A use.  gcc treats this a not a use, that's probably a bug due to tree319  // folding ignoring volatile.320  +(i=k);321  // CHECK-NEXT: load volatile322  // CHECK-NEXT: store volatile323  // CHECK-NEXT: load volatile324 325  // A use. gcc treats this a not a use, that's probably a bug due to tree326  // folding ignoring volatile.327  __real (ci=ci);328  // CHECK-NEXT: load volatile329  // CHECK-NEXT: load volatile330  // CHECK-NEXT: store volatile331  // CHECK-NEXT: store volatile332 333  // A use.334  i + 0;335  // CHECK-NEXT: load volatile336  // CHECK-NEXT: add337 338  // A use.339  (i=j) + i;340  // CHECK-NEXT: load volatile341  // CHECK-NEXT: store volatile342  // CHECK-NEXT: load volatile343  // CHECK-NEXT: load volatile344  // CHECK-NEXT: add345 346  // A use.  gcc treats this as not a use, that's probably a bug due to tree347  // folding ignoring volatile.348  (i=j) + 0;349  // CHECK-NEXT: load volatile350  // CHECK-NEXT: store volatile351  // CHECK-NEXT: load volatile352  // CHECK-NEXT: add353 354  (i,j)=k; // i is also a load in C++11355  // CHECK-NEXT: load volatile [[INT]], ptr @k356  // CHECK11-NEXT: load volatile [[INT]], ptr @i357  // CHECK-NEXT: store volatile {{.*}}, ptr @j358 359  (j=k,i)=i;360  // CHECK-NEXT: load volatile [[INT]], ptr @i361  // CHECK-NEXT: load volatile [[INT]], ptr @k362  // CHECK-NEXT: store volatile {{.*}}, ptr @j363  // CHECK-NEXT: store volatile {{.*}}, ptr @i364 365  // CHECK-NEXT: ret void366}367