249 lines · plain
1; RUN: opt < %s -passes=dfsan -dfsan-abilist=%S/Inputs/abilist.txt -S | FileCheck %s2target 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: define { i1, i7 } @functional({ i32, i1 } %a, [2 x i7] %b)6define {i1, i7} @functional({i32, i1} %a, [2 x i7] %b) {7 %a1 = extractvalue {i32, i1} %a, 18 %b0 = extractvalue [2 x i7] %b, 09 %r0 = insertvalue {i1, i7} undef, i1 %a1, 010 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 111 ret {i1, i7} %r112}13 14define {i1, i7} @call_functional({i32, i1} %a, [2 x i7] %b) {15 ; CHECK-LABEL: @call_functional.dfsan16 ; CHECK-NEXT: %[[#REG:]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]17 ; CHECK-NEXT: %[[#REG+1]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]18 ; CHECK-NEXT: %[[#REG+2]] = extractvalue { i8, i8 } %[[#REG+1]], 019 ; CHECK-NEXT: %[[#REG+3]] = extractvalue { i8, i8 } %[[#REG+1]], 120 ; CHECK-NEXT: %[[#REG+4]] = or i8 %[[#REG+2]], %[[#REG+3]]21 ; CHECK-NEXT: %[[#REG+5]] = extractvalue [2 x i8] %[[#REG]], 022 ; CHECK-NEXT: %[[#REG+6]] = extractvalue [2 x i8] %[[#REG]], 123 ; CHECK-NEXT: %[[#REG+7]] = or i8 %[[#REG+5]], %[[#REG+6]]24 ; CHECK-NEXT: %[[#REG+8]] = or i8 %[[#REG+4]], %[[#REG+7]]25 ; CHECK-NEXT: %[[#REG+9]] = insertvalue { i8, i8 } undef, i8 %[[#REG+8]], 026 ; CHECK-NEXT: %[[#REG+10]] = insertvalue { i8, i8 } %[[#REG+9]], i8 %[[#REG+8]], 127 ; CHECK: store { i8, i8 } %[[#REG+10]], ptr @__dfsan_retval_tls, align [[ALIGN]]28 29 %r = call {i1, i7} @functional({i32, i1} %a, [2 x i7] %b)30 ret {i1, i7} %r31}32 33; CHECK: define { i1, i7 } @discard({ i32, i1 } %a, [2 x i7] %b)34define {i1, i7} @discard({i32, i1} %a, [2 x i7] %b) {35 %a1 = extractvalue {i32, i1} %a, 136 %b0 = extractvalue [2 x i7] %b, 037 %r0 = insertvalue {i1, i7} undef, i1 %a1, 038 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 139 ret {i1, i7} %r140}41 42define {i1, i7} @call_discard({i32, i1} %a, [2 x i7] %b) {43 ; CHECK: @call_discard.dfsan44 ; CHECK: store { i8, i8 } zeroinitializer, ptr @__dfsan_retval_tls, align 245 46 %r = call {i1, i7} @discard({i32, i1} %a, [2 x i7] %b)47 ret {i1, i7} %r48}49 50; CHECK: define { i1, i7 } @uninstrumented({ i32, i1 } %a, [2 x i7] %b)51define {i1, i7} @uninstrumented({i32, i1} %a, [2 x i7] %b) {52 %a1 = extractvalue {i32, i1} %a, 153 %b0 = extractvalue [2 x i7] %b, 054 %r0 = insertvalue {i1, i7} undef, i1 %a1, 055 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 156 ret {i1, i7} %r157}58 59define {i1, i7} @call_uninstrumented({i32, i1} %a, [2 x i7] %b) {60 ; CHECK: @call_uninstrumented.dfsan61 ; CHECK: call void @__dfsan_unimplemented62 ; CHECK: store { i8, i8 } zeroinitializer, ptr @__dfsan_retval_tls, align 263 64 %r = call {i1, i7} @uninstrumented({i32, i1} %a, [2 x i7] %b)65 ret {i1, i7} %r66}67 68define {i1, i7} @call_custom_with_ret({i32, i1} %a, [2 x i7] %b) {69 ; CHECK: @call_custom_with_ret.dfsan70 ; CHECK: %labelreturn = alloca i8, align 171 ; CHECK: [[B:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]72 ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]73 ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 074 ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 175 ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]76 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 077 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 178 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]79 ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)80 ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 181 ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 082 ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 183 ; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]84 ; CHECK: ret { i1, i7 } [[R]]85 86 %r = call {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b)87 ret {i1, i7} %r88}89 90define void @call_custom_without_ret({i32, i1} %a, [2 x i7] %b) {91 ; CHECK: @call_custom_without_ret.dfsan92 ; CHECK: [[B:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]93 ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]94 ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 095 ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 196 ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]97 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 098 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 199 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]100 ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %a, [2 x i7] %b, i8 zeroext [[A01]], i8 zeroext [[B01]])101 102 call void @custom_without_ret({i32, i1} %a, [2 x i7] %b)103 ret void104}105 106define void @call_custom_varg({i32, i1} %a, [2 x i7] %b) {107 ; CHECK: @call_custom_varg.dfsan108 ; CHECK: [[B:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]109 ; CHECK: %labelva = alloca [1 x i8], align 1110 ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]111 ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0112 ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1113 ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]114 ; CHECK: [[V0:%.*]] = getelementptr inbounds nuw [1 x i8], ptr %labelva, i32 0, i32 0115 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0116 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1117 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]118 ; CHECK: store i8 [[B01]], ptr [[V0]], align 1119 ; CHECK: [[V:%.*]] = getelementptr inbounds nuw [1 x i8], ptr %labelva, i32 0, i32 0120 ; CHECK: call void ({ i32, i1 }, i8, ptr, ...) @__dfsw_custom_varg({ i32, i1 } %a, i8 zeroext [[A01]], ptr [[V]], [2 x i7] %b)121 122 call void ({i32, i1}, ...) @custom_varg({i32, i1} %a, [2 x i7] %b)123 ret void124}125 126define {i1, i7} @call_custom_cb({i32, i1} %a, [2 x i7] %b) {127 ; CHECK: define { i1, i7 } @call_custom_cb.dfsan({ i32, i1 } %a, [2 x i7] %b) {128 ; CHECK: %labelreturn = alloca i8, align 1129 ; CHECK: [[B:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]130 ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]131 ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0132 ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1133 ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]134 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0135 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1136 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]137 ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_cb(ptr @cb.dfsan, { i32, i1 } %a, [2 x i7] %b, i8 zeroext 0, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)138 ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1139 ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0140 ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1141 ; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]142 143 %r = call {i1, i7} @custom_cb(ptr @cb, {i32, i1} %a, [2 x i7] %b)144 ret {i1, i7} %r145}146 147define {i1, i7} @custom_cb(ptr %cb, {i32, i1} %a, [2 x i7] %b) {148 ; CHECK: define { i1, i7 } @custom_cb(ptr %cb, { i32, i1 } %a, [2 x i7] %b)149 150 %r = call {i1, i7} %cb({i32, i1} %a, [2 x i7] %b)151 ret {i1, i7} %r152}153 154define {i1, i7} @cb({i32, i1} %a, [2 x i7] %b) {155 ; CHECK: define { i1, i7 } @cb.dfsan({ i32, i1 } %a, [2 x i7] %b)156 ; CHECK: [[BL:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]157 ; CHECK: [[AL:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]158 ; CHECK: [[AL1:%.*]] = extractvalue { i8, i8 } [[AL]], 1159 ; CHECK: [[BL0:%.*]] = extractvalue [2 x i8] [[BL]], 0160 ; CHECK: [[RL0:%.*]] = insertvalue { i8, i8 } zeroinitializer, i8 [[AL1]], 0161 ; CHECK: [[RL:%.*]] = insertvalue { i8, i8 } [[RL0]], i8 [[BL0]], 1162 ; CHECK: store { i8, i8 } [[RL]], ptr @__dfsan_retval_tls, align [[ALIGN]]163 164 %a1 = extractvalue {i32, i1} %a, 1165 %b0 = extractvalue [2 x i7] %b, 0166 %r0 = insertvalue {i1, i7} undef, i1 %a1, 0167 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1168 ret {i1, i7} %r1169}170 171define ptr @ret_custom() {172 ; CHECK: @ret_custom.dfsan173 ; CHECK: store i8 0, ptr @__dfsan_retval_tls, align 2174 ; CHECK: ret {{.*}} @"dfsw$custom_with_ret"175 ret ptr @custom_with_ret176}177 178; CHECK: define linkonce_odr { i1, i7 } @"dfsw$custom_cb"(ptr %0, { i32, i1 } %1, [2 x i7] %2) {179; CHECK: %labelreturn = alloca i8, align 1180; COMM: TODO simplify the expression [[#mul(2,SBYTES) + max(SBYTES,2)]] to181; COMM: [[#mul(3,SBYTES)]], if shadow-tls-alignment is updated to match shadow182; COMM: width bytes.183; CHECK: [[B:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 4), align [[ALIGN:2]]184; CHECK: [[A:%.*]] = load { i8, i8 }, ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN]]185; CHECK: [[CB:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN]]186; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0187; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1188; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]189; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0190; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1191; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]192; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_cb(ptr %0, { i32, i1 } %1, [2 x i7] %2, i8 zeroext [[CB]], i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)193; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1194; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0195; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1196; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]197 198define {i1, i7} @custom_with_ret({i32, i1} %a, [2 x i7] %b) {199 ; CHECK: define linkonce_odr { i1, i7 } @"dfsw$custom_with_ret"({ i32, i1 } %0, [2 x i7] %1)200 ; CHECK: %labelreturn = alloca i8, align 1201 ; CHECK: [[B:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]202 ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]203 ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0204 ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1205 ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]206 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0207 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1208 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]209 ; CHECK: [[R:%.*]] = call { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]], ptr %labelreturn)210 ; CHECK: [[RE:%.*]] = load i8, ptr %labelreturn, align 1211 ; CHECK: [[RS0:%.*]] = insertvalue { i8, i8 } undef, i8 [[RE]], 0212 ; CHECK: [[RS1:%.*]] = insertvalue { i8, i8 } [[RS0]], i8 [[RE]], 1213 ; CHECK: store { i8, i8 } [[RS1]], ptr @__dfsan_retval_tls, align [[ALIGN]]214 ; CHECK: ret { i1, i7 } [[R]]215 %a1 = extractvalue {i32, i1} %a, 1216 %b0 = extractvalue [2 x i7] %b, 0217 %r0 = insertvalue {i1, i7} undef, i1 %a1, 0218 %r1 = insertvalue {i1, i7} %r0, i7 %b0, 1219 ret {i1, i7} %r1220}221 222define void @custom_without_ret({i32, i1} %a, [2 x i7] %b) {223 ; CHECK: define linkonce_odr void @"dfsw$custom_without_ret"({ i32, i1 } %0, [2 x i7] %1)224 ; CHECK: [[B:%.*]] = load [2 x i8], ptr getelementptr (i8, ptr @__dfsan_arg_tls, i64 2), align [[ALIGN:2]]225 ; CHECK: [[A:%.*]] = load { i8, i8 }, ptr @__dfsan_arg_tls, align [[ALIGN]]226 ; CHECK: [[A0:%.*]] = extractvalue { i8, i8 } [[A]], 0227 ; CHECK: [[A1:%.*]] = extractvalue { i8, i8 } [[A]], 1228 ; CHECK: [[A01:%.*]] = or i8 [[A0]], [[A1]]229 ; CHECK: [[B0:%.*]] = extractvalue [2 x i8] [[B]], 0230 ; CHECK: [[B1:%.*]] = extractvalue [2 x i8] [[B]], 1231 ; CHECK: [[B01:%.*]] = or i8 [[B0]], [[B1]]232 ; CHECK: call void @__dfsw_custom_without_ret({ i32, i1 } %0, [2 x i7] %1, i8 zeroext [[A01]], i8 zeroext [[B01]])233 ; CHECK: ret234 ret void235}236 237define void @custom_varg({i32, i1} %a, ...) {238 ; CHECK: define linkonce_odr void @"dfsw$custom_varg"({ i32, i1 } %0, ...)239 ; CHECK: call void @__dfsan_vararg_wrapper240 ; CHECK: unreachable241 ret void242}243 244; CHECK: declare { i1, i7 } @__dfsw_custom_with_ret({ i32, i1 }, [2 x i7], i8, i8, ptr)245; CHECK: declare void @__dfsw_custom_without_ret({ i32, i1 }, [2 x i7], i8, i8)246; CHECK: declare void @__dfsw_custom_varg({ i32, i1 }, i8, ptr, ...)247 248; CHECK: declare { i1, i7 } @__dfsw_custom_cb(ptr, { i32, i1 }, [2 x i7], i8, i8, i8, ptr)249