1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s 3 4 typedef double * __attribute__((align_value(64))) aligned_double; 5 6 // CHECK-LABEL: define {{[^@]+}}@_Z3fooPdS_Rd 7 // CHECK-SAME: (double* align 64 [[X:%.*]], double* align 32 [[Y:%.*]], double* nonnull align 128 dereferenceable(8) [[Z:%.*]]) #0 8 // CHECK-NEXT: entry: 9 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double*, align 8 10 // CHECK-NEXT: [[Y_ADDR:%.*]] = alloca double*, align 8 11 // CHECK-NEXT: [[Z_ADDR:%.*]] = alloca double*, align 8 12 // CHECK-NEXT: store double* [[X]], double** [[X_ADDR]], align 8 13 // CHECK-NEXT: store double* [[Y]], double** [[Y_ADDR]], align 8 14 // CHECK-NEXT: store double* [[Z]], double** [[Z_ADDR]], align 8 15 // CHECK-NEXT: ret void 16 // 17 void foo(aligned_double x, double * y __attribute__((align_value(32))), 18 double & z __attribute__((align_value(128)))) { }; 19 20 struct ad_struct { 21 aligned_double a; 22 }; 23 24 // CHECK-LABEL: define {{[^@]+}}@_Z3fooR9ad_struct 25 // CHECK-SAME: (%struct.ad_struct* nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 26 // CHECK-NEXT: entry: 27 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca %struct.ad_struct*, align 8 28 // CHECK-NEXT: store %struct.ad_struct* [[X]], %struct.ad_struct** [[X_ADDR]], align 8 29 // CHECK-NEXT: [[TMP0:%.*]] = load %struct.ad_struct*, %struct.ad_struct** [[X_ADDR]], align 8 30 // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_AD_STRUCT:%.*]], %struct.ad_struct* [[TMP0]], i32 0, i32 0 31 // CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[A]], align 8 32 // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ] 33 // CHECK-NEXT: ret double* [[TMP1]] 34 // 35 double *foo(ad_struct& x) { 36 37 return x.a; 38 } 39 40 // CHECK-LABEL: define {{[^@]+}}@_Z3gooP9ad_struct 41 // CHECK-SAME: (%struct.ad_struct* [[X:%.*]]) #0 42 // CHECK-NEXT: entry: 43 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca %struct.ad_struct*, align 8 44 // CHECK-NEXT: store %struct.ad_struct* [[X]], %struct.ad_struct** [[X_ADDR]], align 8 45 // CHECK-NEXT: [[TMP0:%.*]] = load %struct.ad_struct*, %struct.ad_struct** [[X_ADDR]], align 8 46 // CHECK-NEXT: [[A:%.*]] = getelementptr inbounds [[STRUCT_AD_STRUCT:%.*]], %struct.ad_struct* [[TMP0]], i32 0, i32 0 47 // CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[A]], align 8 48 // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ] 49 // CHECK-NEXT: ret double* [[TMP1]] 50 // 51 double *goo(ad_struct *x) { 52 53 return x->a; 54 } 55 56 // CHECK-LABEL: define {{[^@]+}}@_Z3barPPd 57 // CHECK-SAME: (double** [[X:%.*]]) #0 58 // CHECK-NEXT: entry: 59 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 60 // CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 61 // CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 62 // CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP0]], align 8 63 // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ] 64 // CHECK-NEXT: ret double* [[TMP1]] 65 // 66 double *bar(aligned_double *x) { 67 68 return *x; 69 } 70 71 // CHECK-LABEL: define {{[^@]+}}@_Z3carRPd 72 // CHECK-SAME: (double** nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 73 // CHECK-NEXT: entry: 74 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 75 // CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 76 // CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 77 // CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[TMP0]], align 8 78 // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ] 79 // CHECK-NEXT: ret double* [[TMP1]] 80 // 81 double *car(aligned_double &x) { 82 83 return x; 84 } 85 86 // CHECK-LABEL: define {{[^@]+}}@_Z3darPPd 87 // CHECK-SAME: (double** [[X:%.*]]) #0 88 // CHECK-NEXT: entry: 89 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 90 // CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 91 // CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 92 // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double*, double** [[TMP0]], i64 5 93 // CHECK-NEXT: [[TMP1:%.*]] = load double*, double** [[ARRAYIDX]], align 8 94 // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[TMP1]], i64 64) ] 95 // CHECK-NEXT: ret double* [[TMP1]] 96 // 97 double *dar(aligned_double *x) { 98 99 return x[5]; 100 } 101 102 aligned_double eep(); 103 // CHECK-LABEL: define {{[^@]+}}@_Z3retv() #0 104 // CHECK-NEXT: entry: 105 // CHECK-NEXT: [[CALL:%.*]] = call double* @_Z3eepv() 106 // CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(double* [[CALL]], i64 64) ] 107 // CHECK-NEXT: ret double* [[CALL]] 108 // 109 double *ret() { 110 111 return eep(); 112 } 113 114 // CHECK-LABEL: define {{[^@]+}}@_Z3no1PPd 115 // CHECK-SAME: (double** [[X:%.*]]) #0 116 // CHECK-NEXT: entry: 117 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 118 // CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 119 // CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 120 // CHECK-NEXT: ret double** [[TMP0]] 121 // 122 double **no1(aligned_double *x) { 123 return x; 124 } 125 126 // CHECK-LABEL: define {{[^@]+}}@_Z3no2RPd 127 // CHECK-SAME: (double** nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 128 // CHECK-NEXT: entry: 129 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 130 // CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 131 // CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 132 // CHECK-NEXT: ret double** [[TMP0]] 133 // 134 double *&no2(aligned_double &x) { 135 return x; 136 } 137 138 // CHECK-LABEL: define {{[^@]+}}@_Z3no3RPd 139 // CHECK-SAME: (double** nonnull align 8 dereferenceable(8) [[X:%.*]]) #0 140 // CHECK-NEXT: entry: 141 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double**, align 8 142 // CHECK-NEXT: store double** [[X]], double*** [[X_ADDR]], align 8 143 // CHECK-NEXT: [[TMP0:%.*]] = load double**, double*** [[X_ADDR]], align 8 144 // CHECK-NEXT: ret double** [[TMP0]] 145 // 146 double **no3(aligned_double &x) { 147 return &x; 148 } 149 150 // CHECK-LABEL: define {{[^@]+}}@_Z3no3Pd 151 // CHECK-SAME: (double* align 64 [[X:%.*]]) #0 152 // CHECK-NEXT: entry: 153 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double*, align 8 154 // CHECK-NEXT: store double* [[X]], double** [[X_ADDR]], align 8 155 // CHECK-NEXT: [[TMP0:%.*]] = load double*, double** [[X_ADDR]], align 8 156 // CHECK-NEXT: [[TMP1:%.*]] = load double, double* [[TMP0]], align 8 157 // CHECK-NEXT: ret double [[TMP1]] 158 // 159 double no3(aligned_double x) { 160 return *x; 161 } 162 163 // CHECK-LABEL: define {{[^@]+}}@_Z3no4Pd 164 // CHECK-SAME: (double* align 64 [[X:%.*]]) #0 165 // CHECK-NEXT: entry: 166 // CHECK-NEXT: [[X_ADDR:%.*]] = alloca double*, align 8 167 // CHECK-NEXT: store double* [[X]], double** [[X_ADDR]], align 8 168 // CHECK-NEXT: [[TMP0:%.*]] = load double*, double** [[X_ADDR]], align 8 169 // CHECK-NEXT: ret double* [[TMP0]] 170 // 171 double *no4(aligned_double x) { 172 return x; 173 } 174 175