1; RUN: opt < %s -msan-check-access-address=0 -S -passes=msan 2>&1 | FileCheck  \
2; RUN: %s
3; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s
4; REQUIRES: x86-registered-target
5
6target 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"
7target triple = "x86_64-unknown-linux-gnu"
8
9declare i32 @llvm.x86.bmi.bzhi.32(i32, i32)
10declare i32 @llvm.x86.bmi.bextr.32(i32, i32)
11declare i32 @llvm.x86.bmi.pdep.32(i32, i32)
12declare i32 @llvm.x86.bmi.pext.32(i32, i32)
13
14declare i64 @llvm.x86.bmi.bzhi.64(i64, i64)
15declare i64 @llvm.x86.bmi.bextr.64(i64, i64)
16declare i64 @llvm.x86.bmi.pdep.64(i64, i64)
17declare i64 @llvm.x86.bmi.pext.64(i64, i64)
18
19define i32 @Test_bzhi_32(i32 %a, i32 %b) sanitize_memory {
20entry:
21  %c = tail call i32 @llvm.x86.bmi.bzhi.32(i32 %a, i32 %b)
22  ret i32 %c
23}
24
25; CHECK-LABEL: @Test_bzhi_32(
26; CHECK-DAG: %[[SA:.*]] = load i32, {{.*}}@__msan_param_tls to i32*)
27; CHECK-DAG: %[[SB:.*]] = load i32, {{.*}}@__msan_param_tls to i64), i64 8)
28; CHECK-DAG: %[[SB0:.*]] = icmp ne i32 %[[SB]], 0
29; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i32
30; CHECK-DAG: %[[X:.*]] = call i32 @llvm.x86.bmi.bzhi.32(i32 %[[SA]], i32 %b)
31; CHECK-DAG: %[[S:.*]] = or i32 %[[SB1]], %[[X]]
32; CHECK-DAG: store i32 %[[S]], {{.*}}@__msan_retval_tls
33; CHECK: ret i32
34
35define i64 @Test_bzhi_64(i64 %a, i64 %b) sanitize_memory {
36entry:
37  %c = tail call i64 @llvm.x86.bmi.bzhi.64(i64 %a, i64 %b)
38  ret i64 %c
39}
40
41; CHECK-LABEL: @Test_bzhi_64(
42; CHECK-DAG: %[[SA:.*]] = load i64, {{.*}}@__msan_param_tls, i32 0, i32 0
43; CHECK-DAG: %[[SB:.*]] = load i64, {{.*}}@__msan_param_tls to i64), i64 8)
44; CHECK-DAG: %[[SB0:.*]] = icmp ne i64 %[[SB]], 0
45; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i64
46; CHECK-DAG: %[[X:.*]] = call i64 @llvm.x86.bmi.bzhi.64(i64 %[[SA]], i64 %b)
47; CHECK-DAG: %[[S:.*]] = or i64 %[[SB1]], %[[X]]
48; CHECK-DAG: store i64 %[[S]], {{.*}}@__msan_retval_tls
49; CHECK: ret i64
50
51
52define i32 @Test_bextr_32(i32 %a, i32 %b) sanitize_memory {
53entry:
54  %c = tail call i32 @llvm.x86.bmi.bextr.32(i32 %a, i32 %b)
55  ret i32 %c
56}
57
58; CHECK-LABEL: @Test_bextr_32(
59; CHECK-DAG: %[[SA:.*]] = load i32, {{.*}}@__msan_param_tls to i32*)
60; CHECK-DAG: %[[SB:.*]] = load i32, {{.*}}@__msan_param_tls to i64), i64 8)
61; CHECK-DAG: %[[SB0:.*]] = icmp ne i32 %[[SB]], 0
62; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i32
63; CHECK-DAG: %[[X:.*]] = call i32 @llvm.x86.bmi.bextr.32(i32 %[[SA]], i32 %b)
64; CHECK-DAG: %[[S:.*]] = or i32 %[[SB1]], %[[X]]
65; CHECK-DAG: store i32 %[[S]], {{.*}}@__msan_retval_tls
66; CHECK: ret i32
67
68define i64 @Test_bextr_64(i64 %a, i64 %b) sanitize_memory {
69entry:
70  %c = tail call i64 @llvm.x86.bmi.bextr.64(i64 %a, i64 %b)
71  ret i64 %c
72}
73
74; CHECK-LABEL: @Test_bextr_64(
75; CHECK-DAG: %[[SA:.*]] = load i64, {{.*}}@__msan_param_tls, i32 0, i32 0
76; CHECK-DAG: %[[SB:.*]] = load i64, {{.*}}@__msan_param_tls to i64), i64 8)
77; CHECK-DAG: %[[SB0:.*]] = icmp ne i64 %[[SB]], 0
78; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i64
79; CHECK-DAG: %[[X:.*]] = call i64 @llvm.x86.bmi.bextr.64(i64 %[[SA]], i64 %b)
80; CHECK-DAG: %[[S:.*]] = or i64 %[[SB1]], %[[X]]
81; CHECK-DAG: store i64 %[[S]], {{.*}}@__msan_retval_tls
82; CHECK: ret i64
83
84
85define i32 @Test_pdep_32(i32 %a, i32 %b) sanitize_memory {
86entry:
87  %c = tail call i32 @llvm.x86.bmi.pdep.32(i32 %a, i32 %b)
88  ret i32 %c
89}
90
91; CHECK-LABEL: @Test_pdep_32(
92; CHECK-DAG: %[[SA:.*]] = load i32, {{.*}}@__msan_param_tls to i32*)
93; CHECK-DAG: %[[SB:.*]] = load i32, {{.*}}@__msan_param_tls to i64), i64 8)
94; CHECK-DAG: %[[SB0:.*]] = icmp ne i32 %[[SB]], 0
95; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i32
96; CHECK-DAG: %[[X:.*]] = call i32 @llvm.x86.bmi.pdep.32(i32 %[[SA]], i32 %b)
97; CHECK-DAG: %[[S:.*]] = or i32 %[[SB1]], %[[X]]
98; CHECK-DAG: store i32 %[[S]], {{.*}}@__msan_retval_tls
99; CHECK: ret i32
100
101define i64 @Test_pdep_64(i64 %a, i64 %b) sanitize_memory {
102entry:
103  %c = tail call i64 @llvm.x86.bmi.pdep.64(i64 %a, i64 %b)
104  ret i64 %c
105}
106
107; CHECK-LABEL: @Test_pdep_64(
108; CHECK-DAG: %[[SA:.*]] = load i64, {{.*}}@__msan_param_tls, i32 0, i32 0
109; CHECK-DAG: %[[SB:.*]] = load i64, {{.*}}@__msan_param_tls to i64), i64 8)
110; CHECK-DAG: %[[SB0:.*]] = icmp ne i64 %[[SB]], 0
111; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i64
112; CHECK-DAG: %[[X:.*]] = call i64 @llvm.x86.bmi.pdep.64(i64 %[[SA]], i64 %b)
113; CHECK-DAG: %[[S:.*]] = or i64 %[[SB1]], %[[X]]
114; CHECK-DAG: store i64 %[[S]], {{.*}}@__msan_retval_tls
115; CHECK: ret i64
116
117define i32 @Test_pext_32(i32 %a, i32 %b) sanitize_memory {
118entry:
119  %c = tail call i32 @llvm.x86.bmi.pext.32(i32 %a, i32 %b)
120  ret i32 %c
121}
122
123; CHECK-LABEL: @Test_pext_32(
124; CHECK-DAG: %[[SA:.*]] = load i32, {{.*}}@__msan_param_tls to i32*)
125; CHECK-DAG: %[[SB:.*]] = load i32, {{.*}}@__msan_param_tls to i64), i64 8)
126; CHECK-DAG: %[[SB0:.*]] = icmp ne i32 %[[SB]], 0
127; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i32
128; CHECK-DAG: %[[X:.*]] = call i32 @llvm.x86.bmi.pext.32(i32 %[[SA]], i32 %b)
129; CHECK-DAG: %[[S:.*]] = or i32 %[[SB1]], %[[X]]
130; CHECK-DAG: store i32 %[[S]], {{.*}}@__msan_retval_tls
131; CHECK: ret i32
132
133define i64 @Test_pext_64(i64 %a, i64 %b) sanitize_memory {
134entry:
135  %c = tail call i64 @llvm.x86.bmi.pext.64(i64 %a, i64 %b)
136  ret i64 %c
137}
138
139; CHECK-LABEL: @Test_pext_64(
140; CHECK-DAG: %[[SA:.*]] = load i64, {{.*}}@__msan_param_tls, i32 0, i32 0
141; CHECK-DAG: %[[SB:.*]] = load i64, {{.*}}@__msan_param_tls to i64), i64 8)
142; CHECK-DAG: %[[SB0:.*]] = icmp ne i64 %[[SB]], 0
143; CHECK-DAG: %[[SB1:.*]] = sext i1 %[[SB0]] to i64
144; CHECK-DAG: %[[X:.*]] = call i64 @llvm.x86.bmi.pext.64(i64 %[[SA]], i64 %b)
145; CHECK-DAG: %[[S:.*]] = or i64 %[[SB1]], %[[X]]
146; CHECK-DAG: store i64 %[[S]], {{.*}}@__msan_retval_tls
147; CHECK: ret i64
148