-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[InstCombine] Simplify the pointer operand of store if writing to null is UB #127979
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
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesProof: https://alive2.llvm.org/ce/z/mzVj-u llvm-project/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Lines 1027 to 1075 in 44feae8
Full diff: https://github.com/llvm/llvm-project/pull/127979.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
index 4b42e86e25161..d5534c15cca76 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
@@ -1437,6 +1437,20 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) {
if (isa<UndefValue>(Val))
return eraseInstFromFunction(SI);
+ // TODO: Add a helper to simplify the pointer operand for all memory
+ // instructions.
+ // store val, (select (cond, null, P)) -> store val, P
+ // store val, (select (cond, P, null)) -> store val, P
+ if (!NullPointerIsDefined(SI.getFunction(), SI.getPointerAddressSpace())) {
+ if (SelectInst *Sel = dyn_cast<SelectInst>(Ptr)) {
+ if (isa<ConstantPointerNull>(Sel->getOperand(1)))
+ return replaceOperand(SI, 1, Sel->getOperand(2));
+
+ if (isa<ConstantPointerNull>(Sel->getOperand(2)))
+ return replaceOperand(SI, 1, Sel->getOperand(1));
+ }
+ }
+
return nullptr;
}
diff --git a/llvm/test/Transforms/InstCombine/store.ll b/llvm/test/Transforms/InstCombine/store.ll
index 673395464c85a..0a2b0a5ee7987 100644
--- a/llvm/test/Transforms/InstCombine/store.ll
+++ b/llvm/test/Transforms/InstCombine/store.ll
@@ -345,6 +345,48 @@ define void @store_to_readonly_noalias(ptr readonly noalias %0) {
ret void
}
+define void @store_select_with_null(i1 %cond, ptr %p) {
+; CHECK-LABEL: @store_select_with_null(
+; CHECK-NEXT: store i32 0, ptr [[SEL:%.*]], align 4
+; CHECK-NEXT: ret void
+;
+ %sel = select i1 %cond, ptr %p, ptr null
+ store i32 0, ptr %sel, align 4
+ ret void
+}
+
+define void @store_select_with_null_commuted(i1 %cond, ptr %p) {
+; CHECK-LABEL: @store_select_with_null_commuted(
+; CHECK-NEXT: store i32 0, ptr [[SEL:%.*]], align 4
+; CHECK-NEXT: ret void
+;
+ %sel = select i1 %cond, ptr null, ptr %p
+ store i32 0, ptr %sel, align 4
+ ret void
+}
+
+define void @store_select_with_null_null_is_valid(i1 %cond, ptr %p) null_pointer_is_valid {
+; CHECK-LABEL: @store_select_with_null_null_is_valid(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], ptr [[P:%.*]], ptr null
+; CHECK-NEXT: store i32 0, ptr [[SEL]], align 4
+; CHECK-NEXT: ret void
+;
+ %sel = select i1 %cond, ptr %p, ptr null
+ store i32 0, ptr %sel, align 4
+ ret void
+}
+
+define void @store_select_with_unknown(i1 %cond, ptr %p, ptr %p2) {
+; CHECK-LABEL: @store_select_with_unknown(
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], ptr [[P:%.*]], ptr [[P2:%.*]]
+; CHECK-NEXT: store i32 0, ptr [[SEL]], align 4
+; CHECK-NEXT: ret void
+;
+ %sel = select i1 %cond, ptr %p, ptr %p2
+ store i32 0, ptr %sel, align 4
+ ret void
+}
+
!0 = !{!4, !4, i64 0}
!1 = !{!"omnipotent char", !2}
!2 = !{!"Simple C/C++ TBAA"}
|
I think it's only needed for the first transform, but not the second... |
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.
LGTM
This patch is the follow-up of #127979. It introduces a helper `simplifyNonNullOperand` to avoid duplicate logic. It also addresses the one-use issue in `visitLoadInst`, as discussed in #127979 (comment). The `nonnull` attribute is also supported. Proof: https://alive2.llvm.org/ce/z/MCKgT9
This patch is the follow-up of llvm/llvm-project#127979. It introduces a helper `simplifyNonNullOperand` to avoid duplicate logic. It also addresses the one-use issue in `visitLoadInst`, as discussed in llvm/llvm-project#127979 (comment). The `nonnull` attribute is also supported. Proof: https://alive2.llvm.org/ce/z/MCKgT9
Proof: https://alive2.llvm.org/ce/z/mzVj-u
I will add some follow-up patches to avoid duplicate code, support more memory instructions, and bypass gep instructions.
Before merging with the code in
visitLoadInst
, I need to investigate if the one-use check is necessary:llvm-project/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
Lines 1027 to 1075 in 44feae8