Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@ static cl::opt<bool> ClIgnorePersonalityRoutine(
"list, do not create a wrapper for it."),
cl::Hidden, cl::init(false));

static cl::opt<bool> ClAddGlobalNameSuffix(
"dfsan-add-global-name-suffix",
cl::desc("Whether to add .dfsan suffix to global names"), cl::Hidden,
cl::init(true));

static StringRef getGlobalTypeString(const GlobalValue &G) {
// Types of GlobalVariables are always pointer types.
Type *GType = G.getValueType();
Expand Down Expand Up @@ -1256,6 +1261,9 @@ DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) {
}

void DataFlowSanitizer::addGlobalNameSuffix(GlobalValue *GV) {
if (!ClAddGlobalNameSuffix)
return;

std::string GVName = std::string(GV->getName()), Suffix = ".dfsan";
GV->setName(GVName + Suffix);

Expand Down
95 changes: 54 additions & 41 deletions llvm/test/Instrumentation/DataFlowSanitizer/arith.ll
Original file line number Diff line number Diff line change
@@ -1,73 +1,86 @@
; RUN: opt < %s -passes=dfsan -S | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=dfsan -dfsan-add-global-name-suffix=0 -S | FileCheck %s
target 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"
target triple = "x86_64-unknown-linux-gnu"

define i8 @add(i8 %a, i8 %b) {
; CHECK: @add.dfsan
; CHECK-DAG: %[[#ALABEL:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
; CHECK-DAG: %[[#BLABEL:]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align [[ALIGN]]
; CHECK: %[[#UNION:]] = or i8 %[[#ALABEL]], %[[#BLABEL]]
; CHECK: %c = add i8 %a, %b
; CHECK: store i8 %[[#UNION]], ptr @__dfsan_retval_tls, align [[ALIGN]]
; CHECK: ret i8 %c
; CHECK-LABEL: define i8 @add(
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
; CHECK-NEXT: [[C:%.*]] = add i8 [[A]], [[B]]
; CHECK-NEXT: store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
; CHECK-NEXT: ret i8 [[C]]
;
%c = add i8 %a, %b
ret i8 %c
}

define i8 @sub(i8 %a, i8 %b) {
; CHECK: @sub.dfsan
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: or i8
; CHECK: %c = sub i8 %a, %b
; CHECK: store{{.*}}__dfsan_retval_tls
; CHECK: ret i8 %c
; CHECK-LABEL: define i8 @sub(
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
; CHECK-NEXT: [[C:%.*]] = sub i8 [[A]], [[B]]
; CHECK-NEXT: store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
; CHECK-NEXT: ret i8 [[C]]
;
%c = sub i8 %a, %b
ret i8 %c
}

define i8 @mul(i8 %a, i8 %b) {
; CHECK: @mul.dfsan
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: or i8
; CHECK: %c = mul i8 %a, %b
; CHECK: store{{.*}}__dfsan_retval_tls
; CHECK: ret i8 %c
; CHECK-LABEL: define i8 @mul(
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
; CHECK-NEXT: [[C:%.*]] = mul i8 [[A]], [[B]]
; CHECK-NEXT: store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
; CHECK-NEXT: ret i8 [[C]]
;
%c = mul i8 %a, %b
ret i8 %c
}

define i8 @sdiv(i8 %a, i8 %b) {
; CHECK: @sdiv.dfsan
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: or i8
; CHECK: %c = sdiv i8 %a, %b
; CHECK: store{{.*}}__dfsan_retval_tls
; CHECK: ret i8 %c
; CHECK-LABEL: define i8 @sdiv(
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
; CHECK-NEXT: [[C:%.*]] = sdiv i8 [[A]], [[B]]
; CHECK-NEXT: store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
; CHECK-NEXT: ret i8 [[C]]
;
%c = sdiv i8 %a, %b
ret i8 %c
}

define i8 @udiv(i8 %a, i8 %b) {
; CHECK: @udiv.dfsan
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: or i8
; CHECK: %c = udiv i8 %a, %b
; CHECK: store{{.*}}__dfsan_retval_tls
; CHECK: ret i8 %c
; CHECK-LABEL: define i8 @udiv(
; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__dfsan_arg_tls to i64), i64 2) to ptr), align 2
; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[TMP3:%.*]] = or i8 [[TMP2]], [[TMP1]]
; CHECK-NEXT: [[C:%.*]] = udiv i8 [[A]], [[B]]
; CHECK-NEXT: store i8 [[TMP3]], ptr @__dfsan_retval_tls, align 2
; CHECK-NEXT: ret i8 [[C]]
;
%c = udiv i8 %a, %b
ret i8 %c
}

define double @fneg(double %a) {
; CHECK: @fneg.dfsan
; CHECK: load{{.*}}__dfsan_arg_tls
; CHECK: %c = fneg double %a
; CHECK: store{{.*}}__dfsan_retval_tls
; CHECK: ret double %c
; CHECK-LABEL: define double @fneg(
; CHECK-SAME: double [[A:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[C:%.*]] = fneg double [[A]]
; CHECK-NEXT: store i8 [[TMP1]], ptr @__dfsan_retval_tls, align 2
; CHECK-NEXT: ret double [[C]]
;
%c = fneg double %a
ret double %c
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -S | FileCheck %s
; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-track-origins=1 -S | FileCheck %s --check-prefixes=CHECK,CHECK_ORIGIN
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-add-global-name-suffix=0 -S | FileCheck %s
; RUN: opt < %s -passes=dfsan -dfsan-combine-offset-labels-on-gep=false -dfsan-track-origins=1 -dfsan-add-global-name-suffix=0 -S | FileCheck %s --check-prefix=CHECK_ORIGIN
target 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"
target triple = "x86_64-unknown-linux-gnu"

; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could retain these using --check-globals, but this doesn't really seem relevant for the individual tests.

define ptr @gepop(ptr %p, i32 %a, i32 %b, i32 %c) {
; CHECK: @gepop.dfsan
; CHECK_ORIGIN: %[[#PO:]] = load i32, ptr @__dfsan_arg_origin_tls, align [[ALIGN_O:4]]
; CHECK: %[[#PS:]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN_S:2]]
; CHECK: %e = getelementptr [10 x [20 x i32]], ptr %p, i32 %a, i32 %b, i32 %c
; CHECK: store i8 %[[#PS]], ptr @__dfsan_retval_tls, align [[ALIGN_S]]
; CHECK_ORIGIN: store i32 %[[#PO]], ptr @__dfsan_retval_origin_tls, align [[ALIGN_O]]

; CHECK-LABEL: define ptr @gepop(
; CHECK-SAME: ptr [[P:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[E:%.*]] = getelementptr [10 x [20 x i32]], ptr [[P]], i32 [[A]], i32 [[B]], i32 [[C]]
; CHECK-NEXT: store i8 [[TMP1]], ptr @__dfsan_retval_tls, align 2
; CHECK-NEXT: ret ptr [[E]]
;
; CHECK_ORIGIN-LABEL: define ptr @gepop(
; CHECK_ORIGIN-SAME: ptr [[P:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
; CHECK_ORIGIN-NEXT: [[TMP1:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
; CHECK_ORIGIN-NEXT: [[TMP2:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK_ORIGIN-NEXT: [[E:%.*]] = getelementptr [10 x [20 x i32]], ptr [[P]], i32 [[A]], i32 [[B]], i32 [[C]]
; CHECK_ORIGIN-NEXT: store i8 [[TMP2]], ptr @__dfsan_retval_tls, align 2
; CHECK_ORIGIN-NEXT: store i32 [[TMP1]], ptr @__dfsan_retval_origin_tls, align 4
; CHECK_ORIGIN-NEXT: ret ptr [[E]]
;
%e = getelementptr [10 x [20 x i32]], ptr %p, i32 %a, i32 %b, i32 %c
ret ptr %e
}

164 changes: 127 additions & 37 deletions llvm/test/Instrumentation/DataFlowSanitizer/origin_cached_shadows.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -S | FileCheck %s
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -dfsan-add-global-name-suffix=0 -S | FileCheck %s
;
; %i13 and %i15 have the same key in shadow cache. They should not reuse the same
; shadow because their blocks do not dominate each other. Origin tracking
Expand All @@ -7,43 +8,129 @@
target 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"
target triple = "x86_64-unknown-linux-gnu"

; CHECK: @__dfsan_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]]
define void @cached_shadows(double %arg) {
; CHECK: @cached_shadows.dfsan
; CHECK: [[AO:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align
; CHECK: [[AS:%.*]] = load i8, ptr @__dfsan_arg_tls, align [[ALIGN:2]]
; CHECK: [[L1:.+]]:
; CHECK: {{.*}} = phi i8
; CHECK: {{.*}} = phi i32
; CHECK: {{.*}} = phi double [ 3.000000e+00
; CHECK: [[S_L1:%.*]] = phi i8 [ 0, %[[L0:.*]] ], [ [[S_L7:%.*]], %[[L7:.*]] ]
; CHECK: [[O_L1:%.*]] = phi i32 [ 0, %[[L0]] ], [ [[O_L7:%.*]], %[[L7]] ]
; CHECK: [[V_L1:%.*]] = phi double [ 4.000000e+00, %[[L0]] ], [ [[V_L7:%.*]], %[[L7]] ]
; CHECK: br i1 {{%.+}}, label %[[L2:.*]], label %[[L4:.*]]
; CHECK: [[L2]]:
; CHECK: br i1 {{%.+}}, label %[[L3:.+]], label %[[L7]]
; CHECK: [[L3]]:
; CHECK: [[S_L3:%.*]] = or i8
; CHECK: [[AS_NE_L3:%.*]] = icmp ne i8 [[AS]], 0
; CHECK: [[O_L3:%.*]] = select i1 [[AS_NE_L3]], i32 %{{[0-9]+}}, i32 [[O_L1]]
; CHECK: [[V_L3:%.*]] = fsub double [[V_L1]], %{{.+}}
; CHECK: br label %[[L7]]
; CHECK: [[L4]]:
; CHECK: br i1 %_dfscmp, label %[[L5:.+]], label %[[L6:.+]],
; CHECK: [[L5]]:
; CHECK: br label %[[L6]]
; CHECK: [[L6]]:
; CHECK: [[S_L6:%.*]] = or i8
; CHECK: [[AS_NE_L6:%.*]] = icmp ne i8 [[AS]], 0
; CHECK: [[O_L6:%.*]] = select i1 [[AS_NE_L6]], i32 [[AO]], i32 [[O_L1]]
; CHECK: [[V_L6:%.*]] = fadd double [[V_L1]], %{{.+}}
; CHECK: br label %[[L7]]
; CHECK: [[L7]]:
; CHECK: [[S_L7]] = phi i8 [ [[S_L3]], %[[L3]] ], [ [[S_L1]], %[[L2]] ], [ [[S_L6]], %[[L6]] ]
; CHECK: [[O_L7]] = phi i32 [ [[O_L3]], %[[L3]] ], [ [[O_L1]], %[[L2]] ], [ [[O_L6]], %[[L6]] ]
; CHECK: [[V_L7]] = phi double [ [[V_L3]], %[[L3]] ], [ [[V_L1]], %[[L2]] ], [ [[V_L6]], %[[L6]] ]
; CHECK: br i1 %{{.+}}, label %[[L1]], label %[[L8:.+]]
; CHECK: [[L8]]:
; CHECK-LABEL: define void @cached_shadows(
; CHECK-SAME: double [[ARG:%.*]]) {
; CHECK-NEXT: [[BB:.*]]:
; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @__dfsan_arg_origin_tls, align 4
; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @__dfsan_arg_tls, align 2
; CHECK-NEXT: [[I:%.*]] = alloca double, align 8
; CHECK-NEXT: [[I1:%.*]] = alloca double, align 8
; CHECK-NEXT: [[I2:%.*]] = bitcast ptr [[I]] to ptr
; CHECK-NEXT: [[TMP2:%.*]] = ptrtoint ptr [[I]] to i64
; CHECK-NEXT: [[TMP3:%.*]] = xor i64 [[TMP2]], 87960930222080
; CHECK-NEXT: [[TMP4:%.*]] = inttoptr i64 [[TMP3]] to ptr
; CHECK-NEXT: store i64 0, ptr [[TMP4]], align 1
; CHECK-NEXT: store volatile double 1.000000e+00, ptr [[I]], align 8
; CHECK-NEXT: [[I3:%.*]] = bitcast ptr [[I1]] to ptr
; CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[I1]] to i64
; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], 87960930222080
; CHECK-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
; CHECK-NEXT: store i64 0, ptr [[TMP7]], align 1
; CHECK-NEXT: store volatile double 2.000000e+00, ptr [[I1]], align 8
; CHECK-NEXT: br label %[[BB4:.*]]
; CHECK: [[BB4]]:
; CHECK-NEXT: [[TMP8:%.*]] = phi i8 [ 0, %[[BB]] ], [ [[TMP76:%.*]], %[[BB16:.*]] ]
; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP77:%.*]], %[[BB16]] ]
; CHECK-NEXT: [[I5:%.*]] = phi double [ 3.000000e+00, %[[BB]] ], [ [[I17:%.*]], %[[BB16]] ]
; CHECK-NEXT: [[TMP10:%.*]] = phi i8 [ 0, %[[BB]] ], [ [[TMP78:%.*]], %[[BB16]] ]
; CHECK-NEXT: [[TMP11:%.*]] = phi i32 [ 0, %[[BB]] ], [ [[TMP79:%.*]], %[[BB16]] ]
; CHECK-NEXT: [[I6:%.*]] = phi double [ 4.000000e+00, %[[BB]] ], [ [[I18:%.*]], %[[BB16]] ]
; CHECK-NEXT: [[TMP12:%.*]] = ptrtoint ptr [[I1]] to i64
; CHECK-NEXT: [[TMP13:%.*]] = xor i64 [[TMP12]], 87960930222080
; CHECK-NEXT: [[TMP14:%.*]] = inttoptr i64 [[TMP13]] to ptr
; CHECK-NEXT: [[TMP15:%.*]] = add i64 [[TMP13]], 17592186044416
; CHECK-NEXT: [[TMP16:%.*]] = inttoptr i64 [[TMP15]] to ptr
; CHECK-NEXT: [[TMP17:%.*]] = load i32, ptr [[TMP16]], align 8
; CHECK-NEXT: [[TMP18:%.*]] = load i64, ptr [[TMP14]], align 1
; CHECK-NEXT: [[TMP19:%.*]] = shl i64 [[TMP18]], 32
; CHECK-NEXT: [[TMP20:%.*]] = getelementptr i32, ptr [[TMP16]], i64 1
; CHECK-NEXT: [[TMP21:%.*]] = load i32, ptr [[TMP20]], align 8
; CHECK-NEXT: [[TMP22:%.*]] = lshr i64 [[TMP18]], 32
; CHECK-NEXT: [[TMP23:%.*]] = or i64 [[TMP18]], [[TMP22]]
; CHECK-NEXT: [[TMP24:%.*]] = lshr i64 [[TMP23]], 16
; CHECK-NEXT: [[TMP25:%.*]] = or i64 [[TMP23]], [[TMP24]]
; CHECK-NEXT: [[TMP26:%.*]] = lshr i64 [[TMP25]], 8
; CHECK-NEXT: [[TMP27:%.*]] = or i64 [[TMP25]], [[TMP26]]
; CHECK-NEXT: [[TMP28:%.*]] = trunc i64 [[TMP27]] to i8
; CHECK-NEXT: [[TMP29:%.*]] = icmp ne i64 [[TMP19]], 0
; CHECK-NEXT: [[TMP30:%.*]] = select i1 [[TMP29]], i32 [[TMP17]], i32 [[TMP21]]
; CHECK-NEXT: [[I7:%.*]] = load volatile double, ptr [[I1]], align 8
; CHECK-NEXT: [[I8:%.*]] = fcmp une double [[I7]], 0.000000e+00
; CHECK-NEXT: [[TMP31:%.*]] = ptrtoint ptr [[I1]] to i64
; CHECK-NEXT: [[TMP32:%.*]] = xor i64 [[TMP31]], 87960930222080
; CHECK-NEXT: [[TMP33:%.*]] = inttoptr i64 [[TMP32]] to ptr
; CHECK-NEXT: [[TMP34:%.*]] = add i64 [[TMP32]], 17592186044416
; CHECK-NEXT: [[TMP35:%.*]] = inttoptr i64 [[TMP34]] to ptr
; CHECK-NEXT: [[TMP36:%.*]] = load i32, ptr [[TMP35]], align 8
; CHECK-NEXT: [[TMP37:%.*]] = load i64, ptr [[TMP33]], align 1
; CHECK-NEXT: [[TMP38:%.*]] = shl i64 [[TMP37]], 32
; CHECK-NEXT: [[TMP39:%.*]] = getelementptr i32, ptr [[TMP35]], i64 1
; CHECK-NEXT: [[TMP40:%.*]] = load i32, ptr [[TMP39]], align 8
; CHECK-NEXT: [[TMP41:%.*]] = lshr i64 [[TMP37]], 32
; CHECK-NEXT: [[TMP42:%.*]] = or i64 [[TMP37]], [[TMP41]]
; CHECK-NEXT: [[TMP43:%.*]] = lshr i64 [[TMP42]], 16
; CHECK-NEXT: [[TMP44:%.*]] = or i64 [[TMP42]], [[TMP43]]
; CHECK-NEXT: [[TMP45:%.*]] = lshr i64 [[TMP44]], 8
; CHECK-NEXT: [[TMP46:%.*]] = or i64 [[TMP44]], [[TMP45]]
; CHECK-NEXT: [[TMP47:%.*]] = trunc i64 [[TMP46]] to i8
; CHECK-NEXT: [[TMP48:%.*]] = icmp ne i64 [[TMP38]], 0
; CHECK-NEXT: [[TMP49:%.*]] = select i1 [[TMP48]], i32 [[TMP36]], i32 [[TMP40]]
; CHECK-NEXT: [[I9:%.*]] = load volatile double, ptr [[I1]], align 8
; CHECK-NEXT: br i1 [[I8]], label %[[BB10:.*]], label %[[BB14:.*]]
; CHECK: [[BB10]]:
; CHECK-NEXT: [[I11:%.*]] = fcmp une double [[I9]], 0.000000e+00
; CHECK-NEXT: br i1 [[I11]], label %[[BB12:.*]], label %[[BB16]]
; CHECK: [[BB12]]:
; CHECK-NEXT: [[TMP50:%.*]] = or i8 [[TMP10]], [[TMP1]]
; CHECK-NEXT: [[TMP51:%.*]] = icmp ne i8 [[TMP1]], 0
; CHECK-NEXT: [[TMP52:%.*]] = select i1 [[TMP51]], i32 [[TMP0]], i32 [[TMP11]]
; CHECK-NEXT: [[I13:%.*]] = fsub double [[I6]], [[ARG]]
; CHECK-NEXT: br label %[[BB16]]
; CHECK: [[BB14]]:
; CHECK-NEXT: [[TMP53:%.*]] = ptrtoint ptr [[I]] to i64
; CHECK-NEXT: [[TMP54:%.*]] = xor i64 [[TMP53]], 87960930222080
; CHECK-NEXT: [[TMP55:%.*]] = inttoptr i64 [[TMP54]] to ptr
; CHECK-NEXT: [[TMP56:%.*]] = add i64 [[TMP54]], 17592186044416
; CHECK-NEXT: [[TMP57:%.*]] = inttoptr i64 [[TMP56]] to ptr
; CHECK-NEXT: [[TMP58:%.*]] = insertelement <8 x i8> poison, i8 [[TMP47]], i32 0
; CHECK-NEXT: [[TMP59:%.*]] = insertelement <8 x i8> [[TMP58]], i8 [[TMP47]], i32 1
; CHECK-NEXT: [[TMP60:%.*]] = insertelement <8 x i8> [[TMP59]], i8 [[TMP47]], i32 2
; CHECK-NEXT: [[TMP61:%.*]] = insertelement <8 x i8> [[TMP60]], i8 [[TMP47]], i32 3
; CHECK-NEXT: [[TMP62:%.*]] = insertelement <8 x i8> [[TMP61]], i8 [[TMP47]], i32 4
; CHECK-NEXT: [[TMP63:%.*]] = insertelement <8 x i8> [[TMP62]], i8 [[TMP47]], i32 5
; CHECK-NEXT: [[TMP64:%.*]] = insertelement <8 x i8> [[TMP63]], i8 [[TMP47]], i32 6
; CHECK-NEXT: [[TMP65:%.*]] = insertelement <8 x i8> [[TMP64]], i8 [[TMP47]], i32 7
; CHECK-NEXT: [[TMP66:%.*]] = getelementptr <8 x i8>, ptr [[TMP55]], i32 0
; CHECK-NEXT: store <8 x i8> [[TMP65]], ptr [[TMP66]], align 1
; CHECK-NEXT: [[_DFSCMP:%.*]] = icmp ne i8 [[TMP47]], 0
; CHECK-NEXT: br i1 [[_DFSCMP]], label %[[BB67:.*]], label %[[BB72:.*]], !prof [[PROF1:![0-9]+]]
; CHECK: [[BB67]]:
; CHECK-NEXT: [[TMP68:%.*]] = call i32 @__dfsan_chain_origin(i32 [[TMP49]])
; CHECK-NEXT: [[TMP69:%.*]] = zext i32 [[TMP68]] to i64
; CHECK-NEXT: [[TMP70:%.*]] = shl i64 [[TMP69]], 32
; CHECK-NEXT: [[TMP71:%.*]] = or i64 [[TMP69]], [[TMP70]]
; CHECK-NEXT: store i64 [[TMP71]], ptr [[TMP57]], align 8
; CHECK-NEXT: br label %[[BB72]]
; CHECK: [[BB72]]:
; CHECK-NEXT: store volatile double [[I9]], ptr [[I]], align 8
; CHECK-NEXT: [[TMP73:%.*]] = or i8 [[TMP10]], [[TMP1]]
; CHECK-NEXT: [[TMP74:%.*]] = icmp ne i8 [[TMP1]], 0
; CHECK-NEXT: [[TMP75:%.*]] = select i1 [[TMP74]], i32 [[TMP0]], i32 [[TMP11]]
; CHECK-NEXT: [[I15:%.*]] = fadd double [[I6]], [[ARG]]
; CHECK-NEXT: br label %[[BB16]]
; CHECK: [[BB16]]:
; CHECK-NEXT: [[TMP76]] = phi i8 [ [[TMP10]], %[[BB12]] ], [ [[TMP8]], %[[BB10]] ], [ [[TMP10]], %[[BB72]] ]
; CHECK-NEXT: [[TMP77]] = phi i32 [ [[TMP11]], %[[BB12]] ], [ [[TMP9]], %[[BB10]] ], [ [[TMP11]], %[[BB72]] ]
; CHECK-NEXT: [[I17]] = phi double [ [[I6]], %[[BB12]] ], [ [[I5]], %[[BB10]] ], [ [[I6]], %[[BB72]] ]
; CHECK-NEXT: [[TMP78]] = phi i8 [ [[TMP50]], %[[BB12]] ], [ [[TMP10]], %[[BB10]] ], [ [[TMP73]], %[[BB72]] ]
; CHECK-NEXT: [[TMP79]] = phi i32 [ [[TMP52]], %[[BB12]] ], [ [[TMP11]], %[[BB10]] ], [ [[TMP75]], %[[BB72]] ]
; CHECK-NEXT: [[I18]] = phi double [ [[I13]], %[[BB12]] ], [ [[I6]], %[[BB10]] ], [ [[I15]], %[[BB72]] ]
; CHECK-NEXT: [[I19:%.*]] = fcmp olt double [[I17]], 9.900000e+01
; CHECK-NEXT: br i1 [[I19]], label %[[BB4]], label %[[BB20:.*]]
; CHECK: [[BB20]]:
; CHECK-NEXT: ret void
;
bb:
%i = alloca double, align 8
%i1 = alloca double, align 8
Expand Down Expand Up @@ -83,3 +170,6 @@ bb16: ; preds = %bb14, %bb12, %bb10
bb20: ; preds = %bb16
ret void
}
;.
; CHECK: [[PROF1]] = !{!"branch_weights", i32 1, i32 1048575}
;.
Loading