Skip to content

Commit e687f1f

Browse files
committed
Check identical alignment for atomic instrs
1 parent 3134e69 commit e687f1f

File tree

2 files changed

+164
-1
lines changed

2 files changed

+164
-1
lines changed

llvm/lib/IR/Instruction.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
864864
bool Instruction::hasSameSpecialState(const Instruction *I2,
865865
bool IgnoreAlignment,
866866
bool IntersectAttrs) const {
867-
auto I1 = this;
867+
const auto *I1 = this;
868868
assert(I1->getOpcode() == I2->getOpcode() &&
869869
"Can not compare special state of different instructions");
870870

@@ -917,6 +917,8 @@ bool Instruction::hasSameSpecialState(const Instruction *I2,
917917
FI->getSyncScopeID() == cast<FenceInst>(I2)->getSyncScopeID();
918918
if (const AtomicCmpXchgInst *CXI = dyn_cast<AtomicCmpXchgInst>(I1))
919919
return CXI->isVolatile() == cast<AtomicCmpXchgInst>(I2)->isVolatile() &&
920+
(CXI->getAlign() == cast<AtomicCmpXchgInst>(I2)->getAlign() ||
921+
IgnoreAlignment) &&
920922
CXI->isWeak() == cast<AtomicCmpXchgInst>(I2)->isWeak() &&
921923
CXI->getSuccessOrdering() ==
922924
cast<AtomicCmpXchgInst>(I2)->getSuccessOrdering() &&
@@ -927,6 +929,8 @@ bool Instruction::hasSameSpecialState(const Instruction *I2,
927929
if (const AtomicRMWInst *RMWI = dyn_cast<AtomicRMWInst>(I1))
928930
return RMWI->getOperation() == cast<AtomicRMWInst>(I2)->getOperation() &&
929931
RMWI->isVolatile() == cast<AtomicRMWInst>(I2)->isVolatile() &&
932+
(RMWI->getAlign() == cast<AtomicRMWInst>(I2)->getAlign() ||
933+
IgnoreAlignment) &&
930934
RMWI->getOrdering() == cast<AtomicRMWInst>(I2)->getOrdering() &&
931935
RMWI->getSyncScopeID() == cast<AtomicRMWInst>(I2)->getSyncScopeID();
932936
if (const ShuffleVectorInst *SVI = dyn_cast<ShuffleVectorInst>(I1))

llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919
#include "llvm/Support/Allocator.h"
2020
#include "llvm/Support/Compiler.h"
2121
#include "llvm/Support/SourceMgr.h"
22+
#include "gmock/gmock.h"
2223
#include "gtest/gtest.h"
2324

2425
using namespace llvm;
2526
using namespace IRSimilarity;
2627

28+
using testing::SizeIs;
29+
2730
static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
2831
StringRef ModuleStr) {
2932
SMDiagnostic Err;
@@ -730,6 +733,162 @@ TEST(IRInstructionMapper, StoreDifferentAtomic) {
730733
ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
731734
}
732735

736+
// Checks that atomicrmw that have the different types are mapped to
737+
// different unsigned integers.
738+
TEST(IRInstructionMapper, AtomicRMWDifferentType) {
739+
StringRef ModuleString = R"(
740+
define i32 @f(i32* %a, i64* %b) {
741+
bb0:
742+
%1 = atomicrmw add i32* %a, i32 1 acquire
743+
%2 = atomicrmw add i64* %b, i64 1 acquire
744+
ret i32 0
745+
})";
746+
LLVMContext Context;
747+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
748+
749+
std::vector<IRInstructionData *> InstrList;
750+
std::vector<unsigned> UnsignedVec;
751+
752+
SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
753+
SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
754+
IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
755+
getVectors(*M, Mapper, InstrList, UnsignedVec);
756+
757+
ASSERT_EQ(InstrList.size(), UnsignedVec.size());
758+
ASSERT_THAT(UnsignedVec, SizeIs(3));
759+
EXPECT_NE(UnsignedVec[0], UnsignedVec[1]);
760+
}
761+
762+
// Checks that atomicrmw that have the different aligns are mapped to different
763+
// unsigned integers.
764+
TEST(IRInstructionMapper, AtomicRMWDifferentAlign) {
765+
StringRef ModuleString = R"(
766+
define i32 @f(i32* %a, i32* %b) {
767+
bb0:
768+
%1 = atomicrmw add i32* %a, i32 1 acquire, align 4
769+
%2 = atomicrmw add i32* %b, i32 1 acquire, align 8
770+
ret i32 0
771+
})";
772+
LLVMContext Context;
773+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
774+
775+
std::vector<IRInstructionData *> InstrList;
776+
std::vector<unsigned> UnsignedVec;
777+
778+
SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
779+
SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
780+
IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
781+
getVectors(*M, Mapper, InstrList, UnsignedVec);
782+
783+
ASSERT_EQ(InstrList.size(), UnsignedVec.size());
784+
ASSERT_THAT(UnsignedVec, SizeIs(3));
785+
EXPECT_NE(UnsignedVec[0], UnsignedVec[1]);
786+
}
787+
788+
// Checks that atomicrmw that have the different volatile settings are mapped to
789+
// different unsigned integers.
790+
TEST(IRInstructionMapper, AtomicRMWDifferentVolatile) {
791+
StringRef ModuleString = R"(
792+
define i32 @f(i32* %a, i32* %b) {
793+
bb0:
794+
%1 = atomicrmw volatile add i32* %a, i32 1 acquire
795+
%2 = atomicrmw add i32* %b, i32 1 acquire
796+
ret i32 0
797+
})";
798+
LLVMContext Context;
799+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
800+
801+
std::vector<IRInstructionData *> InstrList;
802+
std::vector<unsigned> UnsignedVec;
803+
804+
SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
805+
SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
806+
IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
807+
getVectors(*M, Mapper, InstrList, UnsignedVec);
808+
809+
ASSERT_EQ(InstrList.size(), UnsignedVec.size());
810+
ASSERT_THAT(UnsignedVec, SizeIs(3));
811+
EXPECT_NE(UnsignedVec[0], UnsignedVec[1]);
812+
}
813+
814+
// Checks that cmpxchg that have the different types are mapped to
815+
// different unsigned integers.
816+
TEST(IRInstructionMapper, AtomicCmpXchgDifferentType) {
817+
StringRef ModuleString = R"(
818+
define i32 @f(i32* %a, i64* %b) {
819+
bb0:
820+
%1 = cmpxchg i32* %a, i32 0, i32 1 monotonic monotonic
821+
%2 = cmpxchg i64* %b, i64 0, i64 1 monotonic monotonic
822+
ret i32 0
823+
})";
824+
LLVMContext Context;
825+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
826+
827+
std::vector<IRInstructionData *> InstrList;
828+
std::vector<unsigned> UnsignedVec;
829+
830+
SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
831+
SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
832+
IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
833+
getVectors(*M, Mapper, InstrList, UnsignedVec);
834+
835+
ASSERT_EQ(InstrList.size(), UnsignedVec.size());
836+
ASSERT_THAT(UnsignedVec, SizeIs(3));
837+
EXPECT_NE(UnsignedVec[0], UnsignedVec[1]);
838+
}
839+
840+
// Checks that cmpxchg that have the different aligns are mapped to different
841+
// unsigned integers.
842+
TEST(IRInstructionMapper, AtomicCmpXchgDifferentAlign) {
843+
StringRef ModuleString = R"(
844+
define i32 @f(i32* %a, i32* %b) {
845+
bb0:
846+
%1 = cmpxchg i32* %a, i32 0, i32 1 monotonic monotonic, align 4
847+
%2 = cmpxchg i32* %b, i32 0, i32 1 monotonic monotonic, align 8
848+
ret i32 0
849+
})";
850+
LLVMContext Context;
851+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
852+
853+
std::vector<IRInstructionData *> InstrList;
854+
std::vector<unsigned> UnsignedVec;
855+
856+
SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
857+
SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
858+
IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
859+
getVectors(*M, Mapper, InstrList, UnsignedVec);
860+
861+
ASSERT_EQ(InstrList.size(), UnsignedVec.size());
862+
ASSERT_THAT(UnsignedVec, SizeIs(3));
863+
EXPECT_NE(UnsignedVec[0], UnsignedVec[1]);
864+
}
865+
866+
// Checks that cmpxchg that have the different volatile settings are mapped to
867+
// different unsigned integers.
868+
TEST(IRInstructionMapper, AtomicCmpXchgDifferentVolatile) {
869+
StringRef ModuleString = R"(
870+
define i32 @f(i32* %a, i32* %b) {
871+
bb0:
872+
%1 = cmpxchg volatile i32* %a, i32 0, i32 1 monotonic monotonic
873+
%2 = cmpxchg i32* %b, i32 0, i32 1 monotonic monotonic
874+
ret i32 0
875+
})";
876+
LLVMContext Context;
877+
std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
878+
879+
std::vector<IRInstructionData *> InstrList;
880+
std::vector<unsigned> UnsignedVec;
881+
882+
SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
883+
SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
884+
IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
885+
getVectors(*M, Mapper, InstrList, UnsignedVec);
886+
887+
ASSERT_EQ(InstrList.size(), UnsignedVec.size());
888+
ASSERT_THAT(UnsignedVec, SizeIs(3));
889+
EXPECT_NE(UnsignedVec[0], UnsignedVec[1]);
890+
}
891+
733892
// Checks that the branch is mapped to legal when the option is set.
734893
TEST(IRInstructionMapper, BranchLegal) {
735894
StringRef ModuleString = R"(

0 commit comments

Comments
 (0)