}
i = CS.arg_begin();
+ const unsigned ShadowArgStart = Args.size();
for (unsigned n = FT->getNumParams(); n != 0; ++i, --n)
Args.push_back(DFSF.getShadow(*i));
CustomCI->setCallingConv(CI->getCallingConv());
CustomCI->setAttributes(CI->getAttributes());
+ // Update the parameter attributes of the custom call instruction to
+ // zero extend the shadow parameters. This is required for targets
+ // which consider ShadowTy an illegal type.
+ for (unsigned n = 0; n < FT->getNumParams(); n++) {
+ const unsigned ArgNo = ShadowArgStart + n;
+ if (CustomCI->getArgOperand(ArgNo)->getType() == DFSF.DFS.ShadowTy)
+ CustomCI->addParamAttr(ArgNo, Attribute::ZExt);
+ }
+
if (!FT->getReturnType()->isVoidTy()) {
LoadInst *LabelLoad = IRB.CreateLoad(DFSF.LabelReturnAlloca);
DFSF.setShadow(CustomCI, LabelLoad);
--- /dev/null
+fun:dfsan_get_label=uninstrumented
+fun:dfsan_get_label=custom
+
+fun:k2=uninstrumented
+fun:k2=custom
+
+fun:k4=uninstrumented
+fun:k4=custom
; CHECK: %[[LABELVA1:.*]] = alloca [2 x i16]
; CHECK: %[[LABELRETURN:.*]] = alloca i16
- ; CHECK: call void @__dfsw_custom1(i32 1, i32 2, i16 0, i16 0)
+ ; CHECK: call void @__dfsw_custom1(i32 1, i32 2, i16 zeroext 0, i16 zeroext 0)
call void @custom1(i32 1, i32 2)
- ; CHECK: call i32 @__dfsw_custom2(i32 1, i32 2, i16 0, i16 0, i16* %[[LABELRETURN]])
+ ; CHECK: call i32 @__dfsw_custom2(i32 1, i32 2, i16 zeroext 0, i16 zeroext 0, i16* %[[LABELRETURN]])
call i32 @custom2(i32 1, i32 2)
- ; CHECK: call void @__dfsw_customcb({{.*}} @"dfst0$customcb", i8* bitcast ({{.*}} @"dfs$cb" to i8*), i16 0)
+ ; CHECK: call void @__dfsw_customcb({{.*}} @"dfst0$customcb", i8* bitcast ({{.*}} @"dfs$cb" to i8*), i16 zeroext 0)
call void @customcb(i32 (i32)* @cb)
; CHECK: %[[LABELVA1_0:.*]] = getelementptr inbounds [2 x i16], [2 x i16]* %[[LABELVA1]], i32 0, i32 0
; CHECK: %[[LABELVA1_1:.*]] = getelementptr inbounds [2 x i16], [2 x i16]* %[[LABELVA1]], i32 0, i32 1
; CHECK: store i16 %{{.*}}, i16* %[[LABELVA1_1]]
; CHECK: %[[LABELVA1_0A:.*]] = getelementptr inbounds [2 x i16], [2 x i16]* %[[LABELVA1]], i32 0, i32 0
- ; CHECK: call void (i32, i16, i16*, ...) @__dfsw_custom3(i32 1, i16 0, i16* %[[LABELVA1_0A]], i32 2, i32 %{{.*}})
+ ; CHECK: call void (i32, i16, i16*, ...) @__dfsw_custom3(i32 1, i16 zeroext 0, i16* %[[LABELVA1_0A]], i32 2, i32 %{{.*}})
call void (i32, ...) @custom3(i32 1, i32 2, i32 %x)
; CHECK: %[[LABELVA2_0:.*]] = getelementptr inbounds [2 x i16], [2 x i16]* %[[LABELVA2]], i32 0, i32 0
; CHECK: %[[LABELVA2_0A:.*]] = getelementptr inbounds [2 x i16], [2 x i16]* %[[LABELVA2]], i32 0, i32 0
- ; CHECK: call i32 (i32, i16, i16*, i16*, ...) @__dfsw_custom4(i32 1, i16 0, i16* %[[LABELVA2_0A]], i16* %[[LABELRETURN]], i32 2, i32 3)
+ ; CHECK: call i32 (i32, i16, i16*, i16*, ...) @__dfsw_custom4(i32 1, i16 zeroext 0, i16* %[[LABELVA2_0A]], i16* %[[LABELRETURN]], i32 2, i32 3)
call i32 (i32, ...) @custom4(i32 1, i32 2, i32 3)
ret void
--- /dev/null
+; RUN: opt -mtriple=x86_64-unknown-linux-gnu < %s -dfsan -S --dfsan-abilist=%S/Inputs/shadow-args-abilist.txt | FileCheck %s
+
+; REQUIRES: x86-registered-target
+
+; Test that the custom abi marks shadow parameters as zero extended.
+
+define i32 @m() {
+entry:
+ %call = call zeroext i16 @dfsan_get_label(i64 signext 56)
+ %conv = zext i16 %call to i32
+ ret i32 %conv
+}
+
+; CHECK-LABEL: @"dfs$m"
+; CHECK: %{{.*}} = call zeroext i16 @__dfsw_dfsan_get_label(i64 signext 56, i16 zeroext 0, i16* %{{.*}})
+
+define i32 @k() {
+entry:
+ %call = call zeroext i16 @k2(i64 signext 56, i64 signext 67)
+ %conv = zext i16 %call to i32
+ ret i32 %conv
+}
+
+; CHECK-LABEL: @"dfs$k"
+; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k2(i64 signext 56, i64 signext 67, i16 zeroext {{.*}}, i16 zeroext {{.*}}, i16* %{{.*}})
+
+define i32 @k3() {
+entry:
+ %call = call zeroext i16 @k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89)
+ %conv = zext i16 %call to i32
+ ret i32 %conv
+}
+
+; CHECK-LABEL: @"dfs$k3"
+; CHECK: %{{.*}} = call zeroext i16 @__dfsw_k4(i64 signext 56, i64 signext 67, i64 signext 78, i64 signext 89, i16 zeroext {{.*}}, i16 zeroext {{.*}}, i16 zeroext {{.*}}, i16 zeroext {{.*}}, i16* %{{.*}})
+
+declare zeroext i16 @dfsan_get_label(i64 signext)
+
+; CHECK-LABEL: @"dfsw$dfsan_get_label"
+; CHECK: %{{.*}} = call i16 @__dfsw_dfsan_get_label(i64 %0, i16 zeroext %1, i16* %{{.*}})
+
+declare zeroext i16 @k2(i64 signext, i64 signext)
+; CHECK-LABEL: @"dfsw$k2"
+; CHECK: %{{.*}} = call i16 @__dfsw_k2(i64 %{{.*}}, i64 %{{.*}}, i16 zeroext %{{.*}}, i16 zeroext %{{.*}}, i16* %{{.*}})
+
+declare zeroext i16 @k4(i64 signext, i64 signext, i64 signext, i64 signext)
+
+; CHECK-LABEL: @"dfsw$k4"
+; CHECK: %{{.*}} = call i16 @__dfsw_k4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}, i16 zeroext %{{.*}}, i16 zeroext %{{.*}}, i16 zeroext %{{.*}}, i16 zeroext %{{.*}}, i16* %{{.*}})
+
+
+; CHECK: declare zeroext i16 @__dfsw_dfsan_get_label(i64 signext, i16, i16*)
+; CHECK: declare zeroext i16 @__dfsw_k2(i64 signext, i64 signext, i16, i16, i16*)
+; CHECK: declare zeroext i16 @__dfsw_k4(i64 signext, i64 signext, i64 signext, i64 signext, i16, i16, i16, i16, i16*)