1; RUN: opt < %s -dfsan -dfsan-track-origins=1 -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_arg_tls = external thread_local(initialexec) global [[TLS_ARR:\[100 x i64\]]] 6; CHECK: @__dfsan_retval_tls = external thread_local(initialexec) global [[TLS_ARR]] 7; CHECK: @__dfsan_shadow_width_bits = weak_odr constant i32 [[#SBITS:]] 8; CHECK: @__dfsan_shadow_width_bytes = weak_odr constant i32 [[#SBYTES:]] 9 10define float @unop(float %f) { 11 ; CHECK: @unop.dfsan 12 ; CHECK: [[FO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 13 ; CHECK: store i32 [[FO]], i32* @__dfsan_retval_origin_tls, align 4 14 15 %r = fneg float %f 16 ret float %r 17} 18 19define i1 @binop(i1 %a, i1 %b) { 20 ; CHECK: @binop.dfsan 21 ; CHECK: [[BO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 1), align 4 22 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 23 ; CHECK: [[BS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align 2 24 ; CHECK: [[NE:%.*]] = icmp ne i[[#SBITS]] [[BS]], 0 25 ; CHECK: [[MO:%.*]] = select i1 [[NE]], i32 [[BO]], i32 [[AO]] 26 ; CHECK: store i32 [[MO]], i32* @__dfsan_retval_origin_tls, align 4 27 28 %r = add i1 %a, %b 29 ret i1 %r 30} 31 32define i8 @castop(i32* %p) { 33 ; CHECK: @castop.dfsan 34 ; CHECK: [[PO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 35 ; CHECK: store i32 [[PO]], i32* @__dfsan_retval_origin_tls, align 4 36 37 %r = ptrtoint i32* %p to i8 38 ret i8 %r 39} 40 41define i1 @cmpop(i1 %a, i1 %b) { 42 ; CHECK: @cmpop.dfsan 43 ; CHECK: [[BO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 1), align 4 44 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 45 ; CHECK: [[BS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align 2 46 ; CHECK: [[NE:%.*]] = icmp ne i[[#SBITS]] [[BS]], 0 47 ; CHECK: [[MO:%.*]] = select i1 [[NE]], i32 [[BO]], i32 [[AO]] 48 ; CHECK: store i32 [[MO]], i32* @__dfsan_retval_origin_tls, align 4 49 50 %r = icmp eq i1 %a, %b 51 ret i1 %r 52} 53 54define i32* @gepop([10 x [20 x i32]]* %p, i32 %a, i32 %b, i32 %c) { 55 ; CHECK: @gepop.dfsan 56 ; CHECK: [[CO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 3), align 4 57 ; CHECK: [[BO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 2), align 4 58 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 1), align 4 59 ; CHECK: [[PO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 60 ; CHECK: [[CS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 6) to i[[#SBITS]]*), align 2 61 ; CHECK: [[BS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 4) to i[[#SBITS]]*), align 2 62 ; CHECK: [[AS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align 2 63 ; CHECK: [[AS_NE:%.*]] = icmp ne i[[#SBITS]] [[AS]], 0 64 ; CHECK: [[APO:%.*]] = select i1 [[AS_NE]], i32 [[AO]], i32 [[PO]] 65 ; CHECK: [[BS_NE:%.*]] = icmp ne i[[#SBITS]] [[BS]], 0 66 ; CHECK: [[ABPO:%.*]] = select i1 [[BS_NE]], i32 [[BO]], i32 [[APO]] 67 ; CHECK: [[CS_NE:%.*]] = icmp ne i[[#SBITS]] [[CS]], 0 68 ; CHECK: [[ABCPO:%.*]] = select i1 [[CS_NE]], i32 [[CO]], i32 [[ABPO]] 69 ; CHECK: store i32 [[ABCPO]], i32* @__dfsan_retval_origin_tls, align 4 70 71 %e = getelementptr [10 x [20 x i32]], [10 x [20 x i32]]* %p, i32 %a, i32 %b, i32 %c 72 ret i32* %e 73} 74 75define i32 @eeop(<4 x i32> %a, i32 %b) { 76 ; CHECK: @eeop.dfsan 77 ; CHECK: [[BO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 1), align 4 78 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 79 ; CHECK: [[BS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align 2 80 ; CHECK: [[NE:%.*]] = icmp ne i[[#SBITS]] [[BS]], 0 81 ; CHECK: [[MO:%.*]] = select i1 [[NE]], i32 [[BO]], i32 [[AO]] 82 ; CHECK: store i32 [[MO]], i32* @__dfsan_retval_origin_tls, align 4 83 84 %e = extractelement <4 x i32> %a, i32 %b 85 ret i32 %e 86} 87 88define <4 x i32> @ieop(<4 x i32> %p, i32 %a, i32 %b) { 89 ; CHECK: @ieop.dfsan 90 ; CHECK: [[BO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 2), align 4 91 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 1), align 4 92 ; CHECK: [[PO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 93 ; CHECK: [[BS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 4) to i[[#SBITS]]*), align 2 94 ; CHECK: [[AS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align 2 95 ; CHECK: [[AS_NE:%.*]] = icmp ne i[[#SBITS]] [[AS]], 0 96 ; CHECK: [[APO:%.*]] = select i1 [[AS_NE]], i32 [[AO]], i32 [[PO]] 97 ; CHECK: [[BS_NE:%.*]] = icmp ne i[[#SBITS]] [[BS]], 0 98 ; CHECK: [[ABPO:%.*]] = select i1 [[BS_NE]], i32 [[BO]], i32 [[APO]] 99 ; CHECK: store i32 [[ABPO]], i32* @__dfsan_retval_origin_tls, align 4 100 101 %e = insertelement <4 x i32> %p, i32 %a, i32 %b 102 ret <4 x i32> %e 103} 104 105define <4 x i32> @svop(<4 x i32> %a, <4 x i32> %b) { 106 ; CHECK: @svop.dfsan 107 ; CHECK: [[BO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 1), align 4 108 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 109 ; CHECK: [[BS:%.*]] = load i[[#SBITS]], i[[#SBITS]]* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 2) to i[[#SBITS]]*), align 2 110 ; CHECK: [[NE:%.*]] = icmp ne i[[#SBITS]] [[BS]], 0 111 ; CHECK: [[MO:%.*]] = select i1 [[NE]], i32 [[BO]], i32 [[AO]] 112 ; CHECK: store i32 [[MO]], i32* @__dfsan_retval_origin_tls, align 4 113 114 %e = shufflevector <4 x i32> %a, <4 x i32> %b, <4 x i32> <i32 0, i32 4, i32 1, i32 5> 115 ret <4 x i32> %e 116} 117 118define i32 @evop({i32, float} %a) { 119 ; CHECK: @evop.dfsan 120 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 121 ; CHECK: store i32 [[AO]], i32* @__dfsan_retval_origin_tls, align 4 122 123 %e = extractvalue {i32, float} %a, 0 124 ret i32 %e 125} 126 127define {i32, {float, float}} @ivop({i32, {float, float}} %a, {float, float} %b) { 128 ; CHECK: @ivop.dfsan 129 ; CHECK: [[BO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 1), align 4 130 ; CHECK: [[AO:%.*]] = load i32, i32* getelementptr inbounds ([200 x i32], [200 x i32]* @__dfsan_arg_origin_tls, i64 0, i64 0), align 4 131 ; COMM: TODO simplify the expression [[#mul(2,SBYTES) + max(SBYTES,2)]] to 132 ; COMM: [[#mul(3,SBYTES)]], if shadow-tls-alignment is updated to match shadow 133 ; CHECK: [[BS:%.*]] = load { i[[#SBITS]], i[[#SBITS]] }, { i[[#SBITS]], i[[#SBITS]] }* inttoptr (i64 add (i64 ptrtoint ([100 x i64]* @__dfsan_arg_tls to i64), i64 [[#mul(2,SBYTES) + max(SBYTES,2)]]) to { i[[#SBITS]], i[[#SBITS]] }*), align 2 134 ; CHECK: [[BS0:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[BS]], 0 135 ; CHECK: [[BS1:%.*]] = extractvalue { i[[#SBITS]], i[[#SBITS]] } [[BS]], 1 136 ; CHECK: [[BS01:%.*]] = or i[[#SBITS]] [[BS0]], [[BS1]] 137 ; CHECK: [[NE:%.*]] = icmp ne i[[#SBITS]] [[BS01]], 0 138 ; CHECK: [[MO:%.*]] = select i1 [[NE]], i32 [[BO]], i32 [[AO]] 139 ; CHECK: store i32 [[MO]], i32* @__dfsan_retval_origin_tls, align 4 140 141 %e = insertvalue {i32, {float, float}} %a, {float, float} %b, 1 142 ret {i32, {float, float}} %e 143}