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