Skip to content

Commit 30420bc

Browse files
[IRSim] Make sure that commutative intrinsics are treated as function calls without commutativity
Created to fix: #53537 Some intrinsics functions are considered commutative since they are performing operations like addition or multiplication. Some of these have extra parameters to provide extra information that are not part of the operation itself and are not commutative. This makes sure that if an instruction that is an intrinsic takes the non commutative path to handle this case. Reviewer: paquette Closes Issue #53537 Differential Revision: https://reviews.llvm.org/D118807
1 parent a96dbb9 commit 30420bc

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

llvm/lib/Analysis/IRSimilarityIdentifier.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,8 @@ bool IRSimilarityCandidate::compareStructure(
791791
// We have different paths for commutative instructions and non-commutative
792792
// instructions since commutative instructions could allow multiple mappings
793793
// to certain values.
794-
if (IA->isCommutative() && !isa<FPMathOperator>(IA)) {
794+
if (IA->isCommutative() && !isa<FPMathOperator>(IA) &&
795+
!isa<IntrinsicInst>(IA)) {
795796
if (!compareCommutativeOperandMapping(
796797
{A, OperValsA, ValueNumberMappingA},
797798
{B, OperValsB, ValueNumberMappingB}))

llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,6 +2608,39 @@ TEST(IRSimilarityIdentifier, CommutativeSimilarity) {
26082608
}
26092609
}
26102610

2611+
// This test makes sure that intrinsic functions that are marked commutative
2612+
// are still treated as non-commutative since they are function calls.
2613+
TEST(IRSimilarityIdentifier, InstrinsicCommutative) {
2614+
// If treated as commutative, we will fail to find a valid mapping, causing
2615+
// an assertion error.
2616+
StringRef ModuleString = R"(
2617+
define void @foo() {
2618+
entry:
2619+
%0 = call i16 @llvm.smul.fix.i16(i16 16384, i16 16384, i32 15)
2620+
store i16 %0, i16* undef, align 1
2621+
%1 = icmp eq i16 undef, 8192
2622+
call void @bar()
2623+
%2 = call i16 @llvm.smul.fix.i16(i16 -16384, i16 16384, i32 15)
2624+
store i16 %2, i16* undef, align 1
2625+
%3 = icmp eq i16 undef, -8192
2626+
call void @bar()
2627+
%4 = call i16 @llvm.smul.fix.i16(i16 -16384, i16 -16384, i32 15)
2628+
ret void
2629+
}
2630+
2631+
declare void @bar()
2632+
2633+
; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
2634+
declare i16 @llvm.smul.fix.i16(i16, i16, i32 immarg))";
2635+
LLVMContext Context;
2636+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
2637+
2638+
std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
2639+
getSimilarities(*M, SimilarityCandidates);
2640+
2641+
ASSERT_TRUE(SimilarityCandidates.size() == 0);
2642+
}
2643+
26112644
// This test checks to see whether we can detect different structure in
26122645
// commutative instructions. In this case, the second operand in the second
26132646
// add is different.

0 commit comments

Comments
 (0)