[compiler-rt] r355348 - [msan] Instrument x86 BMI intrinsics.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 4 14:58:20 PST 2019
Author: eugenis
Date: Mon Mar 4 14:58:20 2019
New Revision: 355348
URL: http://llvm.org/viewvc/llvm-project?rev=355348&view=rev
Log:
[msan] Instrument x86 BMI intrinsics.
Summary:
They simply shuffle bits. MSan needs to do the same with shadow bits,
after making sure that the shuffle mask is fully initialized.
Reviewers: pcc, vitalybuka
Subscribers: hiraditya, #sanitizers, llvm-commits
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D58858
Modified:
compiler-rt/trunk/lib/msan/tests/msan_test.cc
Modified: compiler-rt/trunk/lib/msan/tests/msan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/tests/msan_test.cc?rev=355348&r1=355347&r2=355348&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Mon Mar 4 14:58:20 2019
@@ -169,7 +169,7 @@ static bool TrackingOrigins() {
#define EXPECT_POISONED(x) ExpectPoisoned(x)
-template<typename T>
+template <typename T>
void ExpectPoisoned(const T& t) {
EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
}
@@ -4644,3 +4644,149 @@ TEST(MemorySanitizer, MallocUsableSizeTe
delete int_ptr;
}
#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
+
+static bool HaveBmi() {
+#ifdef __x86_64__
+ U4 a = 0, b = 0, c = 0, d = 0;
+ asm("cpuid\n\t" : "=a"(a), "=D"(b), "=c"(c), "=d"(d) : "a"(7));
+ const U4 kBmi12Mask = (1U<<3) | (1U<<8);
+ return b | kBmi12Mask;
+#else
+ return false;
+#endif
+}
+
+__attribute__((target("bmi,bmi2")))
+static void TestBZHI() {
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bzhi_si(Poisoned<U4>(0xABCDABCD, 0xFF000000), 24));
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_si(Poisoned<U4>(0xABCDABCD, 0xFF800000), 24));
+ // Second operand saturates.
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_si(Poisoned<U4>(0xABCDABCD, 0x80000000), 240));
+ // Any poison in the second operand poisons output.
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_si(0xABCDABCD, Poisoned<U4>(1, 1)));
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_si(0xABCDABCD, Poisoned<U4>(1, 0x80000000)));
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_si(0xABCDABCD, Poisoned<U4>(1, 0xFFFFFFFF)));
+
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bzhi_di(Poisoned<U8>(0xABCDABCDABCDABCD, 0xFF00000000000000ULL), 56));
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_di(Poisoned<U8>(0xABCDABCDABCDABCD, 0xFF80000000000000ULL), 56));
+ // Second operand saturates.
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_di(Poisoned<U8>(0xABCDABCDABCDABCD, 0x8000000000000000ULL), 240));
+ // Any poison in the second operand poisons output.
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_di(0xABCDABCDABCDABCD, Poisoned<U8>(1, 1)));
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_di(0xABCDABCDABCDABCD, Poisoned<U8>(1, 0x8000000000000000ULL)));
+ EXPECT_POISONED(
+ __builtin_ia32_bzhi_di(0xABCDABCDABCDABCD, Poisoned<U8>(1, 0xFFFFFFFF00000000ULL)));
+}
+
+inline U4 bextr_imm(U4 start, U4 len) {
+ start &= 0xFF;
+ len &= 0xFF;
+ return (len << 8) | start;
+}
+
+__attribute__((target("bmi,bmi2")))
+static void TestBEXTR() {
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u32(Poisoned<U4>(0xABCDABCD, 0xFF), bextr_imm(0, 8)));
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u32(Poisoned<U4>(0xABCDABCD, 0xFF), bextr_imm(7, 8)));
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bextr_u32(Poisoned<U4>(0xABCDABCD, 0xFF), bextr_imm(8, 8)));
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bextr_u32(Poisoned<U4>(0xABCDABCD, 0xFF), bextr_imm(8, 800)));
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u32(Poisoned<U4>(0xABCDABCD, 0xFF), bextr_imm(7, 800)));
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bextr_u32(Poisoned<U4>(0xABCDABCD, 0xFF), bextr_imm(5, 0)));
+
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u32(0xABCDABCD, Poisoned<U4>(bextr_imm(7, 800), 1)));
+ EXPECT_POISONED(__builtin_ia32_bextr_u32(
+ 0xABCDABCD, Poisoned<U4>(bextr_imm(7, 800), 0x80000000)));
+
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u64(Poisoned<U8>(0xABCDABCD, 0xFF), bextr_imm(0, 8)));
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u64(Poisoned<U8>(0xABCDABCD, 0xFF), bextr_imm(7, 8)));
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bextr_u64(Poisoned<U8>(0xABCDABCD, 0xFF), bextr_imm(8, 8)));
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bextr_u64(Poisoned<U8>(0xABCDABCD, 0xFF), bextr_imm(8, 800)));
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u64(Poisoned<U8>(0xABCDABCD, 0xFF), bextr_imm(7, 800)));
+ EXPECT_NOT_POISONED(
+ __builtin_ia32_bextr_u64(Poisoned<U8>(0xABCDABCD, 0xFF), bextr_imm(5, 0)));
+
+ // Poison in the top half.
+ EXPECT_NOT_POISONED(__builtin_ia32_bextr_u64(
+ Poisoned<U8>(0xABCDABCD, 0xFF0000000000), bextr_imm(32, 8)));
+ EXPECT_POISONED(__builtin_ia32_bextr_u64(
+ Poisoned<U8>(0xABCDABCD, 0xFF0000000000), bextr_imm(32, 9)));
+
+ EXPECT_POISONED(
+ __builtin_ia32_bextr_u64(0xABCDABCD, Poisoned<U8>(bextr_imm(7, 800), 1)));
+ EXPECT_POISONED(__builtin_ia32_bextr_u64(
+ 0xABCDABCD, Poisoned<U8>(bextr_imm(7, 800), 0x80000000)));
+}
+
+__attribute__((target("bmi,bmi2")))
+static void TestPDEP() {
+ U4 x = Poisoned<U4>(0, 0xFF00);
+ EXPECT_NOT_POISONED(__builtin_ia32_pdep_si(x, 0xFF));
+ EXPECT_POISONED(__builtin_ia32_pdep_si(x, 0x1FF));
+ EXPECT_NOT_POISONED(__builtin_ia32_pdep_si(x, 0xFF00));
+ EXPECT_POISONED(__builtin_ia32_pdep_si(x, 0x1FF00));
+
+ EXPECT_NOT_POISONED(__builtin_ia32_pdep_si(x, 0x1FF00) & 0xFF);
+ EXPECT_POISONED(__builtin_ia32_pdep_si(0, Poisoned<U4>(0xF, 1)));
+
+ U8 y = Poisoned<U8>(0, 0xFF00);
+ EXPECT_NOT_POISONED(__builtin_ia32_pdep_di(y, 0xFF));
+ EXPECT_POISONED(__builtin_ia32_pdep_di(y, 0x1FF));
+ EXPECT_NOT_POISONED(__builtin_ia32_pdep_di(y, 0xFF0000000000));
+ EXPECT_POISONED(__builtin_ia32_pdep_di(y, 0x1FF000000000000));
+
+ EXPECT_NOT_POISONED(__builtin_ia32_pdep_di(y, 0x1FF00) & 0xFF);
+ EXPECT_POISONED(__builtin_ia32_pdep_di(0, Poisoned<U4>(0xF, 1)));
+}
+
+__attribute__((target("bmi,bmi2")))
+static void TestPEXT() {
+ U4 x = Poisoned<U4>(0, 0xFF00);
+ EXPECT_NOT_POISONED(__builtin_ia32_pext_si(x, 0xFF));
+ EXPECT_POISONED(__builtin_ia32_pext_si(x, 0x1FF));
+ EXPECT_POISONED(__builtin_ia32_pext_si(x, 0x100));
+ EXPECT_POISONED(__builtin_ia32_pext_si(x, 0x1000));
+ EXPECT_NOT_POISONED(__builtin_ia32_pext_si(x, 0x10000));
+
+ EXPECT_POISONED(__builtin_ia32_pext_si(0xFF00, Poisoned<U4>(0xFF, 1)));
+
+ U8 y = Poisoned<U8>(0, 0xFF0000000000);
+ EXPECT_NOT_POISONED(__builtin_ia32_pext_di(y, 0xFF00000000));
+ EXPECT_POISONED(__builtin_ia32_pext_di(y, 0x1FF00000000));
+ EXPECT_POISONED(__builtin_ia32_pext_di(y, 0x10000000000));
+ EXPECT_POISONED(__builtin_ia32_pext_di(y, 0x100000000000));
+ EXPECT_NOT_POISONED(__builtin_ia32_pext_di(y, 0x1000000000000));
+
+ EXPECT_POISONED(__builtin_ia32_pext_di(0xFF00, Poisoned<U8>(0xFF, 1)));
+}
+
+TEST(MemorySanitizer, Bmi) {
+ if (HaveBmi()) {
+ TestBZHI();
+ TestBEXTR();
+ TestPDEP();
+ TestPEXT();
+ }
+}
More information about the llvm-commits
mailing list