Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[msan] Handle llvm.bitreverse by applying intrinsic to shadow #125606

Merged
merged 1 commit into from
Feb 4, 2025

Conversation

thurstond
Copy link
Contributor

llvm.bitreverse was incorrectly handled by the heuristic handler, because it did not reverse the bits of the shadow.

This updates the instrumentation to use the handler from #114490 and updates the test from #125592

llvm.bitreverse was incorrectly handled by the heuristic handler,
because it did not reverse the bits of the shadow.

This updates the instrumentation to use the handler from
llvm#114490 and  updates the test from llvm#125592
@llvmbot
Copy link
Member

llvmbot commented Feb 4, 2025

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Thurston Dang (thurstond)

Changes

llvm.bitreverse was incorrectly handled by the heuristic handler, because it did not reverse the bits of the shadow.

This updates the instrumentation to use the handler from #114490 and updates the test from #125592


Full diff: https://github.com/llvm/llvm-project/pull/125606.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp (+4)
  • (modified) llvm/test/Instrumentation/MemorySanitizer/bitreverse.ll (+30-17)
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index a4f7e43f041c38..eab15aca00d24c 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -4298,6 +4298,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
     case Intrinsic::abs:
       handleAbsIntrinsic(I);
       break;
+    case Intrinsic::bitreverse:
+      handleIntrinsicByApplyingToShadow(I, I.getIntrinsicID(),
+                                        /*trailingVerbatimArgs*/ 0);
+      break;
     case Intrinsic::is_fpclass:
       handleIsFpClass(I);
       break;
diff --git a/llvm/test/Instrumentation/MemorySanitizer/bitreverse.ll b/llvm/test/Instrumentation/MemorySanitizer/bitreverse.ll
index 72aefe3065e403..f1b6181289967a 100644
--- a/llvm/test/Instrumentation/MemorySanitizer/bitreverse.ll
+++ b/llvm/test/Instrumentation/MemorySanitizer/bitreverse.ll
@@ -1,9 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
 ; RUN: opt < %s -passes=msan -S | FileCheck %s
 ;
-; The heuristic handler for llvm.reverse is incorrect because it doesn't
-; reverse the shadow.
-;
 ; Forked from llvm/test/CodeGen/X86/bitreverse.ll
 
 target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
@@ -16,8 +13,9 @@ define <2 x i16> @test_bitreverse_v2i16(<2 x i16> %a) nounwind #0 {
 ; CHECK-SAME: <2 x i16> [[A:%.*]]) #[[ATTR1:[0-9]+]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i16>, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[A]])
-; CHECK-NEXT:    store <2 x i16> [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store <2 x i16> [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret <2 x i16> [[B]]
 ;
   %b = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %a)
@@ -31,8 +29,9 @@ define i64 @test_bitreverse_i64(i64 %a) nounwind #0 {
 ; CHECK-SAME: i64 [[A:%.*]]) #[[ATTR1]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i64, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[A]])
-; CHECK-NEXT:    store i64 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i64 [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i64 [[B]]
 ;
   %b = call i64 @llvm.bitreverse.i64(i64 %a)
@@ -46,8 +45,9 @@ define i32 @test_bitreverse_i32(i32 %a) nounwind #0 {
 ; CHECK-SAME: i32 [[A:%.*]]) #[[ATTR1]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[A]])
-; CHECK-NEXT:    store i32 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i32 [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i32 [[B]]
 ;
   %b = call i32 @llvm.bitreverse.i32(i32 %a)
@@ -61,8 +61,9 @@ define i24 @test_bitreverse_i24(i24 %a) nounwind #0 {
 ; CHECK-SAME: i24 [[A:%.*]]) #[[ATTR1]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i24, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i24 @llvm.bitreverse.i24(i24 [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call i24 @llvm.bitreverse.i24(i24 [[A]])
-; CHECK-NEXT:    store i24 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i24 [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i24 [[B]]
 ;
   %b = call i24 @llvm.bitreverse.i24(i24 %a)
@@ -76,8 +77,9 @@ define i16 @test_bitreverse_i16(i16 %a) nounwind #0 {
 ; CHECK-SAME: i16 [[A:%.*]]) #[[ATTR1]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[A]])
-; CHECK-NEXT:    store i16 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i16 [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i16 [[B]]
 ;
   %b = call i16 @llvm.bitreverse.i16(i16 %a)
@@ -91,8 +93,9 @@ define i8 @test_bitreverse_i8(i8 %a) #0 {
 ; CHECK-SAME: i8 [[A:%.*]]) #[[ATTR2:[0-9]+]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[A]])
-; CHECK-NEXT:    store i8 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i8 [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i8 [[B]]
 ;
   %b = call i8 @llvm.bitreverse.i8(i8 %a)
@@ -106,8 +109,9 @@ define i4 @test_bitreverse_i4(i4 %a) #0 {
 ; CHECK-SAME: i4 [[A:%.*]]) #[[ATTR2]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i4, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call i4 @llvm.bitreverse.i4(i4 [[A]])
-; CHECK-NEXT:    store i4 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i4 [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i4 [[B]]
 ;
   %b = call i4 @llvm.bitreverse.i4(i4 %a)
@@ -120,8 +124,9 @@ define <2 x i16> @fold_v2i16() #0 {
 ; CHECK-LABEL: define <2 x i16> @fold_v2i16(
 ; CHECK-SAME: ) #[[ATTR2]] {
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP1:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> zeroinitializer)
 ; CHECK-NEXT:    [[B:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> <i16 15, i16 3840>)
-; CHECK-NEXT:    store <2 x i16> zeroinitializer, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store <2 x i16> [[TMP1]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret <2 x i16> [[B]]
 ;
   %b = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> <i16 15, i16 3840>)
@@ -132,8 +137,9 @@ define i24 @fold_i24() #0 {
 ; CHECK-LABEL: define i24 @fold_i24(
 ; CHECK-SAME: ) #[[ATTR2]] {
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP1:%.*]] = call i24 @llvm.bitreverse.i24(i24 0)
 ; CHECK-NEXT:    [[B:%.*]] = call i24 @llvm.bitreverse.i24(i24 4096)
-; CHECK-NEXT:    store i24 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i24 [[TMP1]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i24 [[B]]
 ;
   %b = call i24 @llvm.bitreverse.i24(i24 4096)
@@ -144,8 +150,9 @@ define i8 @fold_i8() #0 {
 ; CHECK-LABEL: define i8 @fold_i8(
 ; CHECK-SAME: ) #[[ATTR2]] {
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.bitreverse.i8(i8 0)
 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.bitreverse.i8(i8 15)
-; CHECK-NEXT:    store i8 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i8 [[TMP1]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i8 [[B]]
 ;
   %b = call i8 @llvm.bitreverse.i8(i8 15)
@@ -156,8 +163,9 @@ define i4 @fold_i4() #0 {
 ; CHECK-LABEL: define i4 @fold_i4(
 ; CHECK-SAME: ) #[[ATTR2]] {
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP1:%.*]] = call i4 @llvm.bitreverse.i4(i4 0)
 ; CHECK-NEXT:    [[B:%.*]] = call i4 @llvm.bitreverse.i4(i4 -8)
-; CHECK-NEXT:    store i4 0, ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i4 [[TMP1]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i4 [[B]]
 ;
   %b = call i4 @llvm.bitreverse.i4(i4 8)
@@ -171,9 +179,11 @@ define i8 @identity_i8(i8 %a) #0 {
 ; CHECK-SAME: i8 [[A:%.*]]) #[[ATTR2]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[A]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[TMP2]])
 ; CHECK-NEXT:    [[C:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[B]])
-; CHECK-NEXT:    store i8 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i8 [[TMP3]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i8 [[C]]
 ;
   %b = call i8 @llvm.bitreverse.i8(i8 %a)
@@ -186,9 +196,11 @@ define <2 x i16> @identity_v2i16(<2 x i16> %a) #0 {
 ; CHECK-SAME: <2 x i16> [[A:%.*]]) #[[ATTR2]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i16>, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[TMP1]])
 ; CHECK-NEXT:    [[B:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[A]])
+; CHECK-NEXT:    [[TMP3:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[TMP2]])
 ; CHECK-NEXT:    [[C:%.*]] = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> [[B]])
-; CHECK-NEXT:    store <2 x i16> [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store <2 x i16> [[TMP3]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret <2 x i16> [[C]]
 ;
   %b = call <2 x i16> @llvm.bitreverse.v2i16(<2 x i16> %a)
@@ -206,8 +218,9 @@ define i528 @large_promotion(i528 %A) nounwind #0 {
 ; CHECK-SAME: i528 [[A:%.*]]) #[[ATTR1]] {
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i528, ptr @__msan_param_tls, align 8
 ; CHECK-NEXT:    call void @llvm.donothing()
+; CHECK-NEXT:    [[TMP2:%.*]] = call i528 @llvm.bitreverse.i528(i528 [[TMP1]])
 ; CHECK-NEXT:    [[Z:%.*]] = call i528 @llvm.bitreverse.i528(i528 [[A]])
-; CHECK-NEXT:    store i528 [[TMP1]], ptr @__msan_retval_tls, align 8
+; CHECK-NEXT:    store i528 [[TMP2]], ptr @__msan_retval_tls, align 8
 ; CHECK-NEXT:    ret i528 [[Z]]
 ;
   %Z = call i528 @llvm.bitreverse.i528(i528 %A)

@thurstond thurstond merged commit f10979f into llvm:main Feb 4, 2025
11 checks passed
Icohedron pushed a commit to Icohedron/llvm-project that referenced this pull request Feb 11, 2025
…25606)

llvm.bitreverse was incorrectly handled by the heuristic handler,
because it did not reverse the bits of the shadow.

This updates the instrumentation to use the handler from
llvm#114490 and updates the test
from llvm#125592
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants