Index: llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -1470,6 +1470,7 @@ } i = CS.arg_begin(); + const unsigned ShadowArgStart = Args.size(); for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) Args.push_back(DFSF.getShadow(*i)); @@ -1505,6 +1506,15 @@ 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); Index: llvm/trunk/test/Instrumentation/DataFlowSanitizer/Inputs/shadow-args-abilist.txt =================================================================== --- llvm/trunk/test/Instrumentation/DataFlowSanitizer/Inputs/shadow-args-abilist.txt +++ llvm/trunk/test/Instrumentation/DataFlowSanitizer/Inputs/shadow-args-abilist.txt @@ -0,0 +1,8 @@ +fun:dfsan_get_label=uninstrumented +fun:dfsan_get_label=custom + +fun:k2=uninstrumented +fun:k2=custom + +fun:k4=uninstrumented +fun:k4=custom Index: llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll =================================================================== --- llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll +++ llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll @@ -47,13 +47,13 @@ ; 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 @@ -61,12 +61,12 @@ ; 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 Index: llvm/trunk/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll =================================================================== --- llvm/trunk/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll +++ llvm/trunk/test/Instrumentation/DataFlowSanitizer/shadow-args-zext.ll @@ -0,0 +1,54 @@ +; 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*)