-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[SandboxIR] Add pointer-diff utility function #110176
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
Changes from 1 commit
cba50ef
c210047
910caea
6280035
9d15da5
031161e
2405d6a
d2609d6
bda7a74
dc1a266
275c57d
79f6901
53fa037
7995061
c9c1810
04c90f1
c44741e
131c020
425a399
33b678c
6d98e45
d9927df
c1bd049
41398fa
996c0f3
b88d4ce
4702aae
499a895
e41dad3
b1fdcd8
3e9c2f6
e86209e
8afa3de
21e6a0a
7d4742f
e54ae3c
ba38c92
3c95326
c0ff3ae
1777605
d48388e
a0d8b51
e3ea7b3
b8bb874
c3b13af
3e838a1
e398058
db4f031
a6d5647
70e1391
b75fa37
9befaba
9b0c0ff
6f1b507
5a17b1d
a7da534
6784dba
c4f127d
581f2cc
5bcf414
2f40c44
b0326ba
c870a82
35999e7
dbb2a59
f8ea07b
c56a942
49a926b
3a39ecf
eed075e
668caaa
7dd0d13
ed7f100
6dc9f69
d94ad93
cfb62e3
bef4cfe
3d97e75
cfe206e
41b0431
f6ac7c2
a914c7a
50211f4
880fc1c
e4e017e
8a8f14e
3d570e8
9d161db
98c0c75
0c0b52f
670eb8c
85bc57b
e8a3c35
05425c2
d700a02
022d52d
e749565
c0608b0
a236280
fda9766
1cfebe6
e454e00
71f3eca
b99c48b
c791604
2cf6df5
977d80e
30f0df4
6546c8a
610e48f
e342c3d
525cf28
c4bc73a
340a30f
0da32fa
7bf9925
8029b33
26cde9b
924f56f
53cd952
b04e524
21c2240
c2c6388
d560303
79a63d8
1633a43
87d09d4
73b1eb3
e60a7bc
b10fec1
c471ee4
8441270
0a62d9f
cceabf6
e94be78
e46f1ef
ddd7fc5
16d02e0
ddc1f9a
a58ba84
30836d6
66fc44e
800c002
3bf02ee
1e48e06
5912fc9
804efae
8aca558
7e192e3
e44ae80
3238a12
e8fb5c6
cdcddf6
9e24c18
b1c73e8
98ac59b
e2bc4cd
d7a9fe8
2a513a4
e1ba42b
fbbe43d
fdb714b
b620f43
30c7bcd
ebd82f1
d518788
92d0f8d
81029c5
9dfe86e
cb8ad32
a94e10c
c3bee3a
c63bad4
e857c73
4bcce92
bbf6eb3
dce7424
8413d18
40ecb4e
125c696
73c13f1
be2f01e
9ba78f4
4166d23
9198cde
754ff3b
920b0d3
398f134
2028330
afbb8fd
f0c2d26
6d35507
9e56ccc
bb39af2
3e584e4
498087d
08866fd
e799269
9a122c1
8b85630
a4778ec
b161fd2
619eb8b
36c9b90
cd2f52b
bacb4e9
79647a4
473e810
9613bd5
f58749d
c164f32
0a81ecd
ff466ce
4f3581b
5620cc4
f4012da
9d757af
79a29c6
f582280
47e5bba
06072fe
7044efd
89ad77e
746ee2a
f50c950
1d3dd08
b2718d8
b072111
c2af11d
06f1889
6c9d4ab
84fb022
b76743e
1f26a95
561ec92
2ab2a86
ca0ffdd
a351d17
99bd6d6
d036f43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,8 +12,12 @@ | |
| #ifndef LLVM_SANDBOXIR_UTILS_H | ||
| #define LLVM_SANDBOXIR_UTILS_H | ||
|
|
||
| #include "llvm/Analysis/LoopAccessAnalysis.h" | ||
| #include "llvm/Analysis/MemoryLocation.h" | ||
| #include "llvm/Analysis/ScalarEvolution.h" | ||
| #include "llvm/Analysis/ValueTracking.h" | ||
| #include "llvm/SandboxIR/SandboxIR.h" | ||
| #include <optional> | ||
|
|
||
| namespace llvm::sandboxir { | ||
|
|
||
|
|
@@ -57,6 +61,35 @@ class Utils { | |
| memoryLocationGetOrNone(const Instruction *I) { | ||
| return llvm::MemoryLocation::getOrNone(cast<llvm::Instruction>(I->Val)); | ||
| } | ||
| /// \Returns true if \p I1 accesses a memory location lower than \p I2. | ||
| template <typename LoadOrStoreT> | ||
| static bool atLowerAddress(LoadOrStoreT *I0, LoadOrStoreT *I1, | ||
|
||
| ScalarEvolution &SE, const DataLayout &DL) { | ||
| auto Diff = getPointerDiffInBytes(I0, I1, SE, DL); | ||
| if (!Diff) | ||
| return false; | ||
| return *Diff > 0; | ||
| } | ||
|
|
||
| /// \Returns the number gap between the memory locations accessed by \p I0 and | ||
|
||
| /// \p I1 in bytes. | ||
| template <typename LoadOrStoreT> | ||
| static std::optional<int> | ||
| getPointerDiffInBytes(LoadOrStoreT *I0, LoadOrStoreT *I1, ScalarEvolution &SE, | ||
| const DataLayout &DL) { | ||
| static_assert(std::is_same<LoadOrStoreT, sandboxir::LoadInst>::value || | ||
|
||
| std::is_same<LoadOrStoreT, sandboxir::StoreInst>::value, | ||
| "Expected sandboxir::Load or sandboxir::Store!"); | ||
| llvm::Value *Opnd0 = I0->getPointerOperand()->Val; | ||
| llvm::Value *Opnd1 = I1->getPointerOperand()->Val; | ||
| llvm::Value *Ptr0 = getUnderlyingObject(Opnd0); | ||
| llvm::Value *Ptr1 = getUnderlyingObject(Opnd1); | ||
| if (Ptr0 != Ptr1) | ||
| return false; | ||
| llvm::Type *ElemTy = llvm::Type::getInt8Ty(SE.getContext()); | ||
| return getPointersDiff(ElemTy, Opnd0, ElemTy, Opnd1, DL, SE, | ||
| /*StrictCheck=*/false, /*CheckType=*/false); | ||
| } | ||
| }; | ||
| } // namespace llvm::sandboxir | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,9 +7,14 @@ | |
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "llvm/SandboxIR/Utils.h" | ||
| #include "llvm/Analysis/AssumptionCache.h" | ||
| #include "llvm/Analysis/BasicAliasAnalysis.h" | ||
| #include "llvm/Analysis/LoopInfo.h" | ||
| #include "llvm/Analysis/TargetLibraryInfo.h" | ||
| #include "llvm/AsmParser/Parser.h" | ||
| #include "llvm/IR/BasicBlock.h" | ||
| #include "llvm/IR/DataLayout.h" | ||
| #include "llvm/IR/Dominators.h" | ||
| #include "llvm/IR/Function.h" | ||
| #include "llvm/IR/Instruction.h" | ||
| #include "llvm/IR/Module.h" | ||
|
|
@@ -54,3 +59,75 @@ define void @foo(ptr %arg0) { | |
| EXPECT_EQ(sandboxir::Utils::memoryLocationGetOrNone(Ld), | ||
| MemoryLocation::getOrNone(LLVMLd)); | ||
| } | ||
|
|
||
| TEST_F(UtilsTest, GetPointerDiffInBytes) { | ||
| parseIR(C, R"IR( | ||
| define void @foo(ptr %ptr) { | ||
| %gep0 = getelementptr inbounds float, ptr %ptr, i64 0 | ||
| %gep1 = getelementptr inbounds float, ptr %ptr, i64 1 | ||
| %gep2 = getelementptr inbounds float, ptr %ptr, i64 2 | ||
| %gep3 = getelementptr inbounds float, ptr %ptr, i64 3 | ||
|
|
||
| %ld0 = load float, ptr %gep0 | ||
| %ld1 = load float, ptr %gep1 | ||
| %ld2 = load float, ptr %gep2 | ||
| %ld3 = load float, ptr %gep3 | ||
|
|
||
| %v2ld0 = load <2 x float>, ptr %gep0 | ||
| %v2ld1 = load <2 x float>, ptr %gep1 | ||
| %v2ld2 = load <2 x float>, ptr %gep2 | ||
| %v2ld3 = load <2 x float>, ptr %gep3 | ||
|
|
||
| %v3ld0 = load <3 x float>, ptr %gep0 | ||
| %v3ld1 = load <3 x float>, ptr %gep1 | ||
| %v3ld2 = load <3 x float>, ptr %gep2 | ||
| %v3ld3 = load <3 x float>, ptr %gep3 | ||
| ret void | ||
| } | ||
| )IR"); | ||
| llvm::Function &LLVMF = *M->getFunction("foo"); | ||
| DominatorTree DT(LLVMF); | ||
| TargetLibraryInfoImpl TLII; | ||
| TargetLibraryInfo TLI(TLII); | ||
| DataLayout DL(M->getDataLayout()); | ||
| AssumptionCache AC(LLVMF); | ||
| BasicAAResult BAA(DL, LLVMF, TLI, AC, &DT); | ||
| AAResults AA(TLI); | ||
| AA.addAAResult(BAA); | ||
| LoopInfo LI(DT); | ||
| ScalarEvolution SE(LLVMF, TLI, AC, DT, LI); | ||
| sandboxir::Context Ctx(C); | ||
|
|
||
| auto &F = *Ctx.createFunction(&LLVMF); | ||
| auto &BB = *F.begin(); | ||
| auto It = std::next(BB.begin(), 4); | ||
| auto *L0 = cast<sandboxir::LoadInst>(&*It++); | ||
| auto *L1 = cast<sandboxir::LoadInst>(&*It++); | ||
| auto *L2 = cast<sandboxir::LoadInst>(&*It++); | ||
| auto *L3 = cast<sandboxir::LoadInst>(&*It++); | ||
| (void)L3; | ||
|
||
|
|
||
| auto *V2L0 = cast<sandboxir::LoadInst>(&*It++); | ||
| auto *V2L1 = cast<sandboxir::LoadInst>(&*It++); | ||
| auto *V2L2 = cast<sandboxir::LoadInst>(&*It++); | ||
| auto *V2L3 = cast<sandboxir::LoadInst>(&*It++); | ||
|
|
||
| auto *V3L0 = cast<sandboxir::LoadInst>(&*It++); | ||
| (void)V3L0; | ||
| auto *V3L1 = cast<sandboxir::LoadInst>(&*It++); | ||
| auto *V3L2 = cast<sandboxir::LoadInst>(&*It++); | ||
| (void)V3L2; | ||
| auto *V3L3 = cast<sandboxir::LoadInst>(&*It++); | ||
| (void)V3L3; | ||
|
|
||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, L1, SE, DL), 4); | ||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, L2, SE, DL), 8); | ||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L1, L0, SE, DL), -4); | ||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V2L0, SE, DL), 0); | ||
|
|
||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V2L1, SE, DL), 4); | ||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V3L1, SE, DL), 4); | ||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L0, V2L2, SE, DL), 8); | ||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L0, V2L3, SE, DL), 12); | ||
| EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L3, V2L0, SE, DL), -12); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about tests for
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also mention that it returns false if we can't determine the diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done