[PATCH] D144933: [instcombine] Simplify separate_storage hints.
David Goldblatt via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 1 09:09:26 PST 2023
davidtgoldblatt updated this revision to Diff 501542.
davidtgoldblatt added a comment.
Nits.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D144933/new/
https://reviews.llvm.org/D144933
Files:
llvm/lib/Analysis/BasicAliasAnalysis.cpp
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/test/Transforms/InstCombine/assume-separate_storage.ll
Index: llvm/test/Transforms/InstCombine/assume-separate_storage.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/assume-separate_storage.ll
@@ -0,0 +1,50 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+declare void @llvm.assume(i1 noundef)
+
+; Just something to let us check that separate_storage bundles don't break
+; anything when given an operand that's not an instruction to fold.
+ at some_global = global i32 777
+
+define void @simple_folding(ptr %a, ptr %b) {
+; CHECK-LABEL: @simple_folding(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[A:%.*]], ptr [[B:%.*]]) ]
+; CHECK-NEXT: ret void
+;
+entry:
+ %p1 = getelementptr i8, ptr %a, i64 123
+ %p2 = getelementptr i8, ptr %b, i64 777
+ call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %p2)]
+ ret void
+}
+
+define i64 @folds_removed_operands(ptr %a, ptr %b, i64 %n1, i64 %n2) {
+; CHECK-LABEL: @folds_removed_operands(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[REASS_ADD:%.*]] = shl i64 [[N2:%.*]], 1
+; CHECK-NEXT: [[Y:%.*]] = add i64 [[REASS_ADD]], [[N1:%.*]]
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[A:%.*]], ptr [[B:%.*]]) ]
+; CHECK-NEXT: ret i64 [[Y]]
+;
+entry:
+ ; Ordinarily, n1 + n2 + n2 would get canonicalized into n1 + (n2 << 1) unless
+ ; there's another use of n1 + n2. Make sure that we remember to put removed
+ ; arguments to separate_storage bundles back on the worklist.
+ %x = add i64 %n1, %n2
+ %y = add i64 %x, %n2
+ %p1 = getelementptr i8, ptr %a, i64 %x
+ call void @llvm.assume(i1 1) ["separate_storage"(ptr %p1, ptr %b)]
+ ret i64 %y
+}
+
+define void @handles_globals(ptr %a) {
+; CHECK-LABEL: @handles_globals(
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "separate_storage"(ptr [[A:%.*]], ptr @some_global) ]
+; CHECK-NEXT: ret void
+;
+ %derived = getelementptr i8, ptr @some_global, i65 3
+ call void @llvm.assume(i1 1) ["separate_storage"(ptr %a, ptr %derived)]
+ ret void
+}
Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2516,6 +2516,27 @@
// TODO: apply range metadata for range check patterns?
}
+ // Separate storage assumptions apply to the underlying allocations, not any
+ // particular pointer within them. When evaluating the hints for AA purposes
+ // we getUnderlyingObject them; by precomputing the answers here we can
+ // avoid having to do so repeatedly there.
+ for (unsigned Idx = 0; Idx < II->getNumOperandBundles(); Idx++) {
+ OperandBundleUse OBU = II->getOperandBundleAt(Idx);
+ if (OBU.getTagName() == "separate_storage") {
+ assert(OBU.Inputs.size() == 2);
+ auto MaybeSimplifyHint = [&](const Use &U) {
+ Value *Hint = U.get();
+ // Not having a limit is safe because InstCombine removes unreachable
+ // code.
+ Value *UnderlyingObject = getUnderlyingObject(Hint, /*MaxLookup*/ 0);
+ if (Hint != UnderlyingObject)
+ replaceUse(const_cast<Use &>(U), UnderlyingObject);
+ };
+ MaybeSimplifyHint(OBU.Inputs[0]);
+ MaybeSimplifyHint(OBU.Inputs[1]);
+ }
+ }
+
// Convert nonnull assume like:
// %A = icmp ne i32* %PTR, null
// call void @llvm.assume(i1 %A)
Index: llvm/lib/Analysis/BasicAliasAnalysis.cpp
===================================================================
--- llvm/lib/Analysis/BasicAliasAnalysis.cpp
+++ llvm/lib/Analysis/BasicAliasAnalysis.cpp
@@ -1516,6 +1516,8 @@
assert(OBU.Inputs.size() == 2);
const Value *Hint1 = OBU.Inputs[0].get();
const Value *Hint2 = OBU.Inputs[1].get();
+ // This is often a no-op; instcombine rewrites this for us. No-op
+ // getUnderlyingObject calls are fast, though.
const Value *HintO1 = getUnderlyingObject(Hint1);
const Value *HintO2 = getUnderlyingObject(Hint2);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144933.501542.patch
Type: text/x-patch
Size: 4256 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230301/201316cd/attachment.bin>
More information about the llvm-commits
mailing list