https://github.com/momchil-velikov created https://github.com/llvm/llvm-project/pull/210335
Call instructions with operand bundles may be assigned the same value number, even if operand bundles differ. The GVN may eliminate one of the calls in favour of another and drop one of the operand bundles. Work around this by assigning unique value numbers to calls with operand bundles. >From ee5c81489e276d8c6f5c8d8b2ae281b8939c94c0 Mon Sep 17 00:00:00 2001 From: Momchil Velikov <[email protected]> Date: Wed, 15 Jul 2026 15:41:09 +0100 Subject: [PATCH] [GVN] Assign unique VNs to calls with operand bundles Call instructions with operand bundles may be assigned the same value number, even if operand bundles differ. The GVN may eliminate one of the calls in favour of another and drop one of the operand bundles. Work around this by assigning unique value numbers to calls with operand bundles. --- llvm/lib/Transforms/Scalar/GVN.cpp | 6 ++++++ .../Transforms/GVN/operand-bundle-unique-vn.ll | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 llvm/test/Transforms/GVN/operand-bundle-unique-vn.ll diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp index f16d1fe9ca893..10b9dd77a3acb 100644 --- a/llvm/lib/Transforms/Scalar/GVN.cpp +++ b/llvm/lib/Transforms/Scalar/GVN.cpp @@ -539,6 +539,12 @@ uint32_t GVNPass::ValueTable::lookupOrAddCall(CallInst *C) { return NextValueNumber++; } + // Conservatively assign unique value numbers to calls with operand bundles. + if (C->hasOperandBundles()) { + ValueNumbering[C] = NextValueNumber; + return NextValueNumber++; + } + if (AA->doesNotAccessMemory(C)) { Expression Exp = createExpr(C); uint32_t E = assignExpNewValueNum(Exp).first; diff --git a/llvm/test/Transforms/GVN/operand-bundle-unique-vn.ll b/llvm/test/Transforms/GVN/operand-bundle-unique-vn.ll new file mode 100644 index 0000000000000..d027a875310f9 --- /dev/null +++ b/llvm/test/Transforms/GVN/operand-bundle-unique-vn.ll @@ -0,0 +1,18 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 +; RUN: opt -S -p gvn < %s | FileCheck %s + +; Check GVN does not eliminate the second call bacause of operand bundle presence. + +define i32 @f(ptr %p) { +; CHECK-LABEL: define i32 @f( +; CHECK-SAME: ptr [[P:%.*]]) { +; CHECK-NEXT: [[U:%.*]] = call i32 @g(i1 true) #[[ATTR1:[0-9]+]] [ "foo"(ptr [[P]]) ] +; CHECK-NEXT: [[V:%.*]] = call i32 @g(i1 true) #[[ATTR1]] [ "foo"(ptr [[P]]) ] +; CHECK-NEXT: ret i32 [[V]] +; + %u = call i32 @g(i1 true) memory(none) ["foo"(ptr %p)] + %v = call i32 @g(i1 true) memory(none) ["foo"(ptr %p)] + ret i32 %v +} + +declare void @g(i1) nounwind willreturn _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
