[llvm] [llvm][SimplifyLibCalls] Add option 'AllowMemcmpToBcmpTransform' (PR #82304)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 19 20:00:15 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Youngsuk Kim (JOE1994)
<details>
<summary>Changes</summary>
Add command line option `AllowMemcmpToBcmpTransform` that controls whether the optimizer is allowed to make the following transform:
memcmp(x, y, Len) == 0 -> bcmp(x, y, Len) == 0
The `bcmp` function was removed in the POSIX.1-2008 standard. The optimizer's default behavior of replacing a call to `memcmp` with `bcmp` without user's acknowledgement can cause inconvenience to users as in #<!-- -->40380 .
Other than 'llvm libc', major libc implementations (glibc, musl, newlib, uClibc, etc.) either alias `bcmp` to `memcmp`, define `bcmp` as a tail call to `memcmp`, or don't define `bcmp` by default. Therefore, the above transformation won't bring benefits to majority of users.
With the new option `AllowMemcmpToBcmpTransforms`, the optimizer will attempt the above transformation only when the user explicitly enables the option.
Closes #<!-- -->73218
---
Full diff: https://github.com/llvm/llvm-project/pull/82304.diff
5 Files Affected:
- (modified) llvm/docs/ReleaseNotes.rst (+4)
- (modified) llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp (+8-1)
- (modified) llvm/test/Transforms/InstCombine/memcmp-1.ll (+1-1)
- (modified) llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll (+2-2)
- (modified) llvm/test/Transforms/InstCombine/strcmp-1.ll (+1-1)
``````````diff
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index 5be00d9d5a5899..cba9475b829180 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -152,6 +152,10 @@ Changes to Sanitizers
Other Changes
-------------
+* The optimizer will no longer try to transform `memcmp(x, y, Len) == 0` to
+ `bcmp(x, y, Len) == 0` unless the command line option
+ `allow-memcmp-to-bcmp-transform` is enabled (off by default).
+
External Open Source Projects Using LLVM 19
===========================================
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 26a34aa99e1b87..66d2f53c16d8ce 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -85,6 +85,13 @@ static cl::opt<unsigned, false, HotColdHintParser> HotNewHintValue(
"hot-new-hint-value", cl::Hidden, cl::init(254),
cl::desc("Value to pass to hot/cold operator new for hot allocation"));
+// Allow transforming `memcmp(x, y, Len) == 0` to `bcmp(x, y, Len) == 0`.
+// Note: `bcmp` was removed from the POSIX.1-2008 standard.
+static cl::opt<bool> AllowMemcmpToBcmpTransform(
+ "allow-memcmp-to-bcmp-transform", cl::Hidden, cl::init(false),
+ cl::desc(
+ "Allow transforming memcmp calls to bcmp calls if deemed beneficial"));
+
//===----------------------------------------------------------------------===//
// Helper Functions
//===----------------------------------------------------------------------===//
@@ -1596,7 +1603,7 @@ Value *LibCallSimplifier::optimizeMemCmp(CallInst *CI, IRBuilderBase &B) {
// memcmp(x, y, Len) == 0 -> bcmp(x, y, Len) == 0
// bcmp can be more efficient than memcmp because it only has to know that
// there is a difference, not how different one is to the other.
- if (isLibFuncEmittable(M, TLI, LibFunc_bcmp) &&
+ if (AllowMemcmpToBcmpTransform && isLibFuncEmittable(M, TLI, LibFunc_bcmp) &&
isOnlyUsedInZeroEqualityComparison(CI)) {
Value *LHS = CI->getArgOperand(0);
Value *RHS = CI->getArgOperand(1);
diff --git a/llvm/test/Transforms/InstCombine/memcmp-1.ll b/llvm/test/Transforms/InstCombine/memcmp-1.ll
index 054896647b5188..3eb74725c537cc 100644
--- a/llvm/test/Transforms/InstCombine/memcmp-1.ll
+++ b/llvm/test/Transforms/InstCombine/memcmp-1.ll
@@ -1,7 +1,7 @@
; Test that the memcmp library call simplifier works correctly.
;
; RUN: opt < %s -passes=instcombine -S | FileCheck --check-prefix=CHECK --check-prefix=NOBCMP %s
-; RUN: opt < %s -passes=instcombine -mtriple=x86_64-unknown-linux-gnu -S | FileCheck --check-prefix=CHECK --check-prefix=BCMP %s
+; RUN: opt < %s -passes=instcombine -mtriple=x86_64-unknown-linux-gnu -S -allow-memcmp-to-bcmp-transform | FileCheck --check-prefix=CHECK --check-prefix=BCMP %s
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32:64"
diff --git a/llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll b/llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll
index 8bbd972ef6e0fa..320cb9eac8dc0e 100644
--- a/llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll
+++ b/llvm/test/Transforms/InstCombine/simplify-libcalls-inreg.ll
@@ -15,8 +15,8 @@ declare i32 @__sprintf_chk(ptr, i32, i32, ptr, ...)
@b = common global [60 x i8] zeroinitializer, align 1
@h = constant [2 x i8] c"h\00"
-; CHECK: declare i32 @bcmp(ptr inreg nocapture, ptr inreg nocapture, i32 inreg)
-; CHECK-NOT: declare i32 @bcmp(ptr nocapture, ptr nocapture, i32)
+; CHECK: declare i32 @memcmp(ptr inreg nocapture noundef, ptr inreg nocapture noundef, i32 inreg noundef)
+; CHECK-NOT: declare i32 @memcmp(ptr nocapture noundef, ptr nocapture noundef, i32)
define i32 @baz(ptr inreg noundef %s2, i32 inreg noundef %n){
%call = call ptr @foo()
diff --git a/llvm/test/Transforms/InstCombine/strcmp-1.ll b/llvm/test/Transforms/InstCombine/strcmp-1.ll
index 0dff891171fe1e..4acfbaf4a48af8 100644
--- a/llvm/test/Transforms/InstCombine/strcmp-1.ll
+++ b/llvm/test/Transforms/InstCombine/strcmp-1.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; Test that the strcmp library call simplifier works correctly.
; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefix=NOBCMP
-; RUN: opt < %s -passes=instcombine -mtriple=unknown-unknown-linux-gnu -S | FileCheck %s --check-prefix=BCMP
+; RUN: opt < %s -passes=instcombine -mtriple=unknown-unknown-linux-gnu -S -allow-memcmp-to-bcmp-transform | FileCheck %s --check-prefix=BCMP
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
``````````
</details>
https://github.com/llvm/llvm-project/pull/82304
More information about the llvm-commits
mailing list