1; RUN: opt < %s -dfsan -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s 2target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 3target triple = "x86_64-unknown-linux-gnu" 4 5; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]] 6; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]] 7 8; CHECK: define { i1, i7 } @functional({ i32, i1 } %a, [2 x i7] %b) 9define {i1, i7} @functional({i32, i1} %a, [2 x i7] %b) { 10 %a1 = extractvalue {i32, i1} %a, 1 11 %b0 = extractvalue [2 x i7] %b, 0 12 %r0 = insertvalue {i1, i7} undef, i1 %a1, 0 13 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1 14 ret {i1, i7} %r1 15} 16 17define {i1, i7} @call_functional({i32, i1} %a, [2 x i7] %b) { 18 ; CHECK-LABEL: @call_functional.dfsan 19 ; CHECK-NEXT: %[[#REG:]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 20 ; CHECK-NEXT: %[[#REG+1]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 21 ; CHECK-NEXT: %[[#REG+2]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } %[[#REG+1]], 0 22 ; CHECK-NEXT: %[[#REG+3]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } %[[#REG+1]], 1 23 ; CHECK-NEXT: %[[#REG+4]] = or i[[#SBITS]] %[[#REG+2]], %[[#REG+3]] 24 ; CHECK-NEXT: %[[#REG+5]] = extractvalue [2 x i[[#SBITS]]] %[[#REG]], 0 25 ; CHECK-NEXT: %[[#REG+6]] = extractvalue [2 x i[[#SBITS]]] %[[#REG]], 1 26 ; CHECK-NEXT: %[[#REG+7]] = or i[[#SBITS]] %[[#REG+5]], %[[#REG+6]] 27 ; CHECK-NEXT: %[[#REG+8]] = or i[[#SBITS]] %[[#REG+4]], %[[#REG+7]] 28 ; CHECK-NEXT: %[[#REG+9]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } undef, i[[#SBITS]] %[[#REG+8]], 0 29 ; CHECK-NEXT: %[[#REG+10]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } %[[#REG+9]], i[[#SBITS]] %[[#REG+8]], 1 30 ; CHECK: store { i[[#SBITS]], i[[#SBITS]] } %[[#REG+10]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 31 32 %r = call {i1, i7} @functional({i32, i1} %a, [2 x i7] %b) 33 ret {i1, i7} %r 34} 35 36; CHECK: define { i1, i7 } @discard({ i32, i1 } %a, [2 x i7] %b) 37define {i1, i7} @discard({i32, i1} %a, [2 x i7] %b) { 38 %a1 = extractvalue {i32, i1} %a, 1 39 %b0 = extractvalue [2 x i7] %b, 0 40 %r0 = insertvalue {i1, i7} undef, i1 %a1, 0 41 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1 42 ret {i1, i7} %r1 43} 44 45define {i1, i7} @call_discard({i32, i1} %a, [2 x i7] %b) { 46 ; CHECK: @call_discard.dfsan 47 ; CHECK: store { i[[#SBITS]], i[[#SBITS]] } zeroinitializer, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align 2 48 49 %r = call {i1, i7} @discard({i32, i1} %a, [2 x i7] %b) 50 ret {i1, i7} %r 51} 52 53; CHECK: define { i1, i7 } @uninstrumented({ i32, i1 } %a, [2 x i7] %b) 54define {i1, i7} @uninstrumented({i32, i1} %a, [2 x i7] %b) { 55 %a1 = extractvalue {i32, i1} %a, 1 56 %b0 = extractvalue [2 x i7] %b, 0 57 %r0 = insertvalue {i1, i7} undef, i1 %a1, 0 58 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1 59 ret {i1, i7} %r1 60} 61 62define {i1, i7} @call_uninstrumented({i32, i1} %a, [2 x i7] %b) { 63 ; CHECK: @call_uninstrumented.dfsan 64 ; CHECK: call void @__dfsan_unimplemented 65 ; CHECK: store { i[[#SBITS]], i[[#SBITS]] } zeroinitializer, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align 2 66 67 %r = call {i1, i7} @uninstrumented({i32, i1} %a, [2 x i7] %b) 68 ret {i1, i7} %r 69} 70 71define {i1, i7} @call_custom_with_ret({i32, i1} %a, [2 x i7] %b) { 72 ; CHECK: @call_custom_with_ret.dfsan 73 ; CHECK: %labelreturn = alloca i[[#SBITS]], align [[#SBYTES]] 74 ; CHECK: [[B:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 75 ; CHECK: [[A:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 76 ; CHECK: [[A0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 0 77 ; CHECK: [[A1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 1 78 ; CHECK: [[A01:%.*]] = or i[[#SBITS]] [[A0]], [[A1]] 79 ; CHECK: [[B0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 0 80 ; CHECK: [[B1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 1 81 ; CHECK: [[B01:%.*]] = or i[[#SBITS]] [[B0]], [[B1]] 82 ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %a, [2 x i7] %b, i[[#SBITS]] zeroext [[A01]], i[[#SBITS]] zeroext [[B01]], i[[#SBITS]]* %labelreturn) 83 ; CHECK: [[RE:%.*]] = load i[[#SBITS]], i[[#SBITS]]* %labelreturn, align [[#SBYTES]] 84 ; CHECK: [[RS0:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } undef, i[[#SBITS]] [[RE]], 0 85 ; CHECK: [[RS1:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[RS0]], i[[#SBITS]] [[RE]], 1 86 ; CHECK: store { i[[#SBITS]], i[[#SBITS]] } [[RS1]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 87 ; CHECK: ret { i1, i7 } [[R]] 88 89 %r = call {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b) 90 ret {i1, i7} %r 91} 92 93define void @call_custom_without_ret({i32, i1} %a, [2 x i7] %b) { 94 ; CHECK: @call_custom_without_ret.dfsan 95 ; CHECK: [[B:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 96 ; CHECK: [[A:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 97 ; CHECK: [[A0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 0 98 ; CHECK: [[A1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 1 99 ; CHECK: [[A01:%.*]] = or i[[#SBITS]] [[A0]], [[A1]] 100 ; CHECK: [[B0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 0 101 ; CHECK: [[B1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 1 102 ; CHECK: [[B01:%.*]] = or i[[#SBITS]] [[B0]], [[B1]] 103 ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %a, [2 x i7] %b, i[[#SBITS]] zeroext [[A01]], i[[#SBITS]] zeroext [[B01]]) 104 105 call void @custom_without_ret({i32, i1} %a, [2 x i7] %b) 106 ret void 107} 108 109define void @call_custom_varg({i32, i1} %a, [2 x i7] %b) { 110 ; CHECK: @call_custom_varg.dfsan 111 ; CHECK: [[B:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 112 ; CHECK: %labelva = alloca [1 x i[[#SBITS]]], align [[#SBYTES]] 113 ; CHECK: [[A:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 114 ; CHECK: [[A0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 0 115 ; CHECK: [[A1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 1 116 ; CHECK: [[A01:%.*]] = or i[[#SBITS]] [[A0]], [[A1]] 117 ; CHECK: [[V0:%.*]] = getelementptr inbounds [1 x i[[#SBITS]]], [1 x i[[#SBITS]]]* %labelva, i32 0, i32 0 118 ; CHECK: [[B0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 0 119 ; CHECK: [[B1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 1 120 ; CHECK: [[B01:%.*]] = or i[[#SBITS]] [[B0]], [[B1]] 121 ; CHECK: store i[[#SBITS]] [[B01]], i[[#SBITS]]* [[V0]], align [[#SBYTES]] 122 ; CHECK: [[V:%.*]] = getelementptr inbounds [1 x i[[#SBITS]]], [1 x i[[#SBITS]]]* %labelva, i32 0, i32 0 123 ; CHECK: call void ({ i32, i1 }, i[[#SBITS]], i[[#SBITS]]*, ...) @__dfsw_custom_varg({ i32, i1 } %a, i[[#SBITS]] zeroext [[A01]], i[[#SBITS]]* [[V]], [2 x i7] %b) 124 125 call void ({i32, i1}, ...) @custom_varg({i32, i1} %a, [2 x i7] %b) 126 ret void 127} 128 129define {i1, i7} @call_custom_cb({i32, i1} %a, [2 x i7] %b) { 130 ; CHECK: define { i1, i7 } @call_custom_cb.dfsan({ i32, i1 } %a, [2 x i7] %b) { 131 ; CHECK: %labelreturn = alloca i[[#SBITS]], align [[#SBYTES]] 132 ; CHECK: [[B:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 133 ; CHECK: [[A:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 134 ; CHECK: [[A0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 0 135 ; CHECK: [[A1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 1 136 ; CHECK: [[A01:%.*]] = or i[[#SBITS]] [[A0]], [[A1]] 137 ; CHECK: [[B0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 0 138 ; CHECK: [[B1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 1 139 ; CHECK: [[B01:%.*]] = or i[[#SBITS]] [[B0]], [[B1]] 140 ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_cb({ i1, i7 } ({ i32, i1 }, [2 x i7])* @cb.dfsan, { i32, i1 } %a, [2 x i7] %b, i[[#SBITS]] zeroext 0, i[[#SBITS]] zeroext [[A01]], i[[#SBITS]] zeroext [[B01]], i[[#SBITS]]* %labelreturn) 141 ; CHECK: [[RE:%.*]] = load i[[#SBITS]], i[[#SBITS]]* %labelreturn, align [[#SBYTES]] 142 ; CHECK: [[RS0:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } undef, i[[#SBITS]] [[RE]], 0 143 ; CHECK: [[RS1:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[RS0]], i[[#SBITS]] [[RE]], 1 144 ; CHECK: store { i[[#SBITS]], i[[#SBITS]] } [[RS1]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 145 146 %r = call {i1, i7} @custom_cb({i1, i7} ({i32, i1}, [2 x i7])* @cb, {i32, i1} %a, [2 x i7] %b) 147 ret {i1, i7} %r 148} 149 150define {i1, i7} @custom_cb({i1, i7} ({i32, i1}, [2 x i7])* %cb, {i32, i1} %a, [2 x i7] %b) { 151 ; CHECK: define { i1, i7 } @custom_cb({ i1, i7 } ({ i32, i1 }, [2 x i7])* %cb, { i32, i1 } %a, [2 x i7] %b) 152 153 %r = call {i1, i7} %cb({i32, i1} %a, [2 x i7] %b) 154 ret {i1, i7} %r 155} 156 157define {i1, i7} @cb({i32, i1} %a, [2 x i7] %b) { 158 ; CHECK: define { i1, i7 } @cb.dfsan({ i32, i1 } %a, [2 x i7] %b) 159 ; CHECK: [[BL:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 160 ; CHECK: [[AL:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 161 ; CHECK: [[AL1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[AL]], 1 162 ; CHECK: [[BL0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[BL]], 0 163 ; CHECK: [[RL0:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } zeroinitializer, i[[#SBITS]] [[AL1]], 0 164 ; CHECK: [[RL:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[RL0]], i[[#SBITS]] [[BL0]], 1 165 ; CHECK: store { i[[#SBITS]], i[[#SBITS]] } [[RL]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 166 167 %a1 = extractvalue {i32, i1} %a, 1 168 %b0 = extractvalue [2 x i7] %b, 0 169 %r0 = insertvalue {i1, i7} undef, i1 %a1, 0 170 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1 171 ret {i1, i7} %r1 172} 173 174define {i1, i7} ({i32, i1}, [2 x i7])* @ret_custom() { 175 ; CHECK: @ret_custom.dfsan 176 ; CHECK: store i[[#SBITS]] 0, i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_retval_tls to i[[#SBITS]]*), align 2 177 ; CHECK: ret {{.*}} @"dfsw$custom_with_ret" 178 ret {i1, i7} ({i32, i1}, [2 x i7])* @custom_with_ret 179} 180 181; CHECK: define linkonce_odr { i1, i7 } @"dfsw$custom_cb"({ i1, i7 } ({ i32, i1 }, [2 x i7])* %0, { i32, i1 } %1, [2 x i7] %2) { 182; CHECK: %labelreturn = alloca i[[#SBITS]], align [[#SBYTES]] 183; COMM: TODO simplify the expression [[#mul(2,SBYTES) + max(SBYTES,2)]] to 184; COMM: [[#mul(3,SBYTES)]], if shadow-tls-alignment is updated to match shadow 185; COMM: width bytes. 186; CHECK: [[B:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES) + max(SBYTES,2)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 187; CHECK: [[A:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 188; CHECK: [[CB:%.*]] = load i[[#SBITS]], i[[#SBITS]]* bitcast ([100 x i64]* @__dfsan_arg_tls to i[[#SBITS]]*), align [[ALIGN]] 189; CHECK: [[A0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 0 190; CHECK: [[A1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 1 191; CHECK: [[A01:%.*]] = or i[[#SBITS]] [[A0]], [[A1]] 192; CHECK: [[B0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 0 193; CHECK: [[B1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 1 194; CHECK: [[B01:%.*]] = or i[[#SBITS]] [[B0]], [[B1]] 195; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_cb({ i1, i7 } ({ i32, i1 }, [2 x i7])* %0, { i32, i1 } %1, [2 x i7] %2, i[[#SBITS]] zeroext [[CB]], i[[#SBITS]] zeroext [[A01]], i[[#SBITS]] zeroext [[B01]], i[[#SBITS]]* %labelreturn) 196; CHECK: [[RE:%.*]] = load i[[#SBITS]], i[[#SBITS]]* %labelreturn, align [[#SBYTES]] 197; CHECK: [[RS0:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } undef, i[[#SBITS]] [[RE]], 0 198; CHECK: [[RS1:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[RS0]], i[[#SBITS]] [[RE]], 1 199; CHECK: store { i[[#SBITS]], i[[#SBITS]] } [[RS1]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 200 201define {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b) { 202 ; CHECK: define linkonce_odr { i1, i7 } @"dfsw$custom_with_ret"({ i32, i1 } %0, [2 x i7] %1) 203 ; CHECK: %labelreturn = alloca i[[#SBITS]], align [[#SBYTES]] 204 ; CHECK: [[B:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 205 ; CHECK: [[A:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 206 ; CHECK: [[A0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 0 207 ; CHECK: [[A1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 1 208 ; CHECK: [[A01:%.*]] = or i[[#SBITS]] [[A0]], [[A1]] 209 ; CHECK: [[B0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 0 210 ; CHECK: [[B1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 1 211 ; CHECK: [[B01:%.*]] = or i[[#SBITS]] [[B0]], [[B1]] 212 ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %0, [2 x i7] %1, i[[#SBITS]] zeroext [[A01]], i[[#SBITS]] zeroext [[B01]], i[[#SBITS]]* %labelreturn) 213 ; CHECK: [[RE:%.*]] = load i[[#SBITS]], i[[#SBITS]]* %labelreturn, align [[#SBYTES]] 214 ; CHECK: [[RS0:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } undef, i[[#SBITS]] [[RE]], 0 215 ; CHECK: [[RS1:%.*]] = insertvalue { i[[#SBITS]], i[[#SBITS]] } [[RS0]], i[[#SBITS]] [[RE]], 1 216 ; CHECK: store { i[[#SBITS]], i[[#SBITS]] } [[RS1]], { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_retval_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 217 ; CHECK: ret { i1, i7 } [[R]] 218 %a1 = extractvalue {i32, i1} %a, 1 219 %b0 = extractvalue [2 x i7] %b, 0 220 %r0 = insertvalue {i1, i7} undef, i1 %a1, 0 221 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1 222 ret {i1, i7} %r1 223} 224 225define void @custom_without_ret({i32, i1} %a, [2 x i7] %b) { 226 ; CHECK: define linkonce_odr void @"dfsw$custom_without_ret"({ i32, i1 } %0, [2 x i7] %1) 227 ; CHECK: [[B:%.*]] = load [2 x i[[#SBITS]]], [2 x i[[#SBITS]]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES)]]) to [2 x i[[#SBITS]]]*), align [[ALIGN:2]] 228 ; CHECK: [[A:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* bitcast ([100 x i64]* @__dfsan_arg_tls to { i[[#SBITS]], i[[#SBITS]] }*), align [[ALIGN]] 229 ; CHECK: [[A0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 0 230 ; CHECK: [[A1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[A]], 1 231 ; CHECK: [[A01:%.*]] = or i[[#SBITS]] [[A0]], [[A1]] 232 ; CHECK: [[B0:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 0 233 ; CHECK: [[B1:%.*]] = extractvalue [2 x i[[#SBITS]]] [[B]], 1 234 ; CHECK: [[B01:%.*]] = or i[[#SBITS]] [[B0]], [[B1]] 235 ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %0, [2 x i7] %1, i[[#SBITS]] zeroext [[A01]], i[[#SBITS]] zeroext [[B01]]) 236 ; CHECK: ret 237 ret void 238} 239 240define void @custom_varg({i32, i1} %a, ...) { 241 ; CHECK: define linkonce_odr void @"dfsw$custom_varg"({ i32, i1 } %0, ...) 242 ; CHECK: call void @__dfsan_vararg_wrapper 243 ; CHECK: unreachable 244 ret void 245} 246 247; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i[[#SBITS]], i[[#SBITS]], i[[#SBITS]]*) 248; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i[[#SBITS]], i[[#SBITS]]) 249; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i[[#SBITS]], i[[#SBITS]]*, ...) 250 251; CHECK: declare { i1, i7 } @__dfsw_custom_cb({ i1, i7 } ({ i32, i1 }, [2 x i7])*, { i32, i1 }, [2 x i7], i[[#SBITS]], i[[#SBITS]], i[[#SBITS]], i[[#SBITS]]*) 252