From b4cac6ad69dbe66bc86b7e0a9cd6eea7c62c161f Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Fri, 21 Feb 2025 09:40:09 +0800 Subject: [PATCH 1/6] [IR] Add a helper `Function::isReturnNonNull` --- llvm/include/llvm/IR/Function.h | 5 +++++ llvm/lib/IR/Function.cpp | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index 29041688124bc..7ea8673bedad1 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -731,6 +731,11 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node { /// create a Function) from the Function Src to this one. void copyAttributesFrom(const Function *Src); + /// Return true if the return value is known to be not null. + /// This may be because it has the nonnull attribute, or because at least + /// one byte is dereferenceable and the pointer is in addrspace(0). + bool isReturnNonNull() const; + /// deleteBody - This method deletes the body of the function, and converts /// the linkage to external. /// diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index 5666f0a53866f..d22cf65769e26 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -873,6 +873,17 @@ void Function::copyAttributesFrom(const Function *Src) { setPrologueData(Src->getPrologueData()); } +bool Function::isReturnNonNull() const { + if (hasRetAttribute(Attribute::NonNull)) + return true; + + if (AttributeSets.getRetDereferenceableBytes() > 0 && + !NullPointerIsDefined(this, getReturnType()->getPointerAddressSpace())) + return true; + + return false; +} + MemoryEffects Function::getMemoryEffects() const { return getAttributes().getMemoryEffects(); } From 70dfcf83a6bf580e0df50cc6c50d4ba1f9c5250a Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Fri, 21 Feb 2025 10:13:42 +0800 Subject: [PATCH 2/6] [PhaseOrdering] Add pre-commit tests. NFC. --- .../PhaseOrdering/memset-combine.ll | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 llvm/test/Transforms/PhaseOrdering/memset-combine.ll diff --git a/llvm/test/Transforms/PhaseOrdering/memset-combine.ll b/llvm/test/Transforms/PhaseOrdering/memset-combine.ll new file mode 100644 index 0000000000000..b7afa4121caef --- /dev/null +++ b/llvm/test/Transforms/PhaseOrdering/memset-combine.ll @@ -0,0 +1,19 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 + +; RUN: opt < %s -passes=instcombine,memcpyopt -S | FileCheck %s + +; FIXME: These two memset calls should be merged into a single one. +define void @merge_memset(ptr %p, i1 %cond) { +; CHECK-LABEL: define void @merge_memset( +; CHECK-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], ptr null, ptr [[P]] +; CHECK-NEXT: [[OFF:%.*]] = getelementptr inbounds nuw i8, ptr [[SEL]], i64 4096 +; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[SEL]], i8 0, i64 4864, i1 false) +; CHECK-NEXT: ret void +; + %sel = select i1 %cond, ptr null, ptr %p + tail call void @llvm.memset.p0.i64(ptr noundef nonnull %sel, i8 0, i64 4096, i1 false) + %off = getelementptr inbounds nuw i8, ptr %sel, i64 4096 + tail call void @llvm.memset.p0.i64(ptr noundef nonnull %off, i8 0, i64 768, i1 false) + ret void +} From 57a65fa59634d5a0e207063675ed47ecfe47d44c Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Fri, 21 Feb 2025 10:24:13 +0800 Subject: [PATCH 3/6] [InstCombine] Simplify nonnull pointers --- .../InstCombine/InstCombineCalls.cpp | 18 ++++++-- .../InstCombine/InstCombineInternal.h | 4 ++ .../InstCombineLoadStoreAlloca.cpp | 46 +++++++++---------- .../InstCombine/InstructionCombining.cpp | 10 +++- .../Transforms/InstCombine/nonnull-select.ll | 29 ++++-------- .../PhaseOrdering/load-store-sameval.ll | 7 +-- .../PhaseOrdering/memset-combine.ll | 3 +- 7 files changed, 61 insertions(+), 56 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 400ebcf493713..c8b3d29c3aa98 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3993,10 +3993,20 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) { unsigned ArgNo = 0; for (Value *V : Call.args()) { - if (V->getType()->isPointerTy() && - !Call.paramHasAttr(ArgNo, Attribute::NonNull) && - isKnownNonZero(V, getSimplifyQuery().getWithInstruction(&Call))) - ArgNos.push_back(ArgNo); + if (V->getType()->isPointerTy()) { + // Simplify the nonnull operand before nonnull inference to avoid + // unnecessary queries. + if (Call.paramHasNonNullAttr(ArgNo, /*AllowUndefOrPoison=*/true)) { + if (Value *Res = simplifyNonNullOperand(V)) { + replaceOperand(Call, ArgNo, Res); + Changed = true; + } + } + + if (!Call.paramHasAttr(ArgNo, Attribute::NonNull) && + isKnownNonZero(V, getSimplifyQuery().getWithInstruction(&Call))) + ArgNos.push_back(ArgNo); + } ArgNo++; } diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h index 83e1da98deeda..71c80d4c401f8 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -455,6 +455,10 @@ class LLVM_LIBRARY_VISIBILITY InstCombinerImpl final Instruction *hoistFNegAboveFMulFDiv(Value *FNegOp, Instruction &FMFSource); + /// Simplify \p V given that it is known to be non-null. + /// Returns the simplified value if possible, otherwise returns nullptr. + Value *simplifyNonNullOperand(Value *V); + public: /// Create and insert the idiom we use to indicate a block is unreachable /// without having to rewrite the CFG from within InstCombine. diff --git a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index d5534c15cca76..89fc1051b18dc 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -982,6 +982,19 @@ static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) { return false; } +/// TODO: Recursively simplify nonnull value to handle one-use inbounds GEPs. +Value *InstCombinerImpl::simplifyNonNullOperand(Value *V) { + if (auto *Sel = dyn_cast(V)) { + if (isa(Sel->getOperand(1))) + return Sel->getOperand(2); + + if (isa(Sel->getOperand(2))) + return Sel->getOperand(1); + } + + return nullptr; +} + Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) { Value *Op = LI.getOperand(0); if (Value *Res = simplifyLoadInst(&LI, Op, SQ.getWithInstruction(&LI))) @@ -1059,20 +1072,13 @@ Instruction *InstCombinerImpl::visitLoadInst(LoadInst &LI) { V2->copyMetadata(LI, Metadata::PoisonGeneratingIDs); return SelectInst::Create(SI->getCondition(), V1, V2); } - - // load (select (cond, null, P)) -> load P - if (isa(SI->getOperand(1)) && - !NullPointerIsDefined(SI->getFunction(), - LI.getPointerAddressSpace())) - return replaceOperand(LI, 0, SI->getOperand(2)); - - // load (select (cond, P, null)) -> load P - if (isa(SI->getOperand(2)) && - !NullPointerIsDefined(SI->getFunction(), - LI.getPointerAddressSpace())) - return replaceOperand(LI, 0, SI->getOperand(1)); } } + + if (!NullPointerIsDefined(LI.getFunction(), LI.getPointerAddressSpace())) + if (Value *V = simplifyNonNullOperand(Op)) + return replaceOperand(LI, 0, V); + return nullptr; } @@ -1437,19 +1443,9 @@ Instruction *InstCombinerImpl::visitStoreInst(StoreInst &SI) { if (isa(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(Ptr)) { - if (isa(Sel->getOperand(1))) - return replaceOperand(SI, 1, Sel->getOperand(2)); - - if (isa(Sel->getOperand(2))) - return replaceOperand(SI, 1, Sel->getOperand(1)); - } - } + if (!NullPointerIsDefined(SI.getFunction(), SI.getPointerAddressSpace())) + if (Value *V = simplifyNonNullOperand(Ptr)) + return replaceOperand(SI, 1, V); return nullptr; } diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 5621511570b58..d3af06f63fcd2 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3587,7 +3587,15 @@ Instruction *InstCombinerImpl::visitFree(CallInst &FI, Value *Op) { Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) { Value *RetVal = RI.getReturnValue(); - if (!RetVal || !AttributeFuncs::isNoFPClassCompatibleType(RetVal->getType())) + if (!RetVal) + return nullptr; + + if (RetVal->getType()->isPointerTy() && RI.getFunction()->isReturnNonNull()) { + if (Value *V = simplifyNonNullOperand(RetVal)) + return replaceOperand(RI, 0, V); + } + + if (!AttributeFuncs::isNoFPClassCompatibleType(RetVal->getType())) return nullptr; Function *F = RI.getFunction(); diff --git a/llvm/test/Transforms/InstCombine/nonnull-select.ll b/llvm/test/Transforms/InstCombine/nonnull-select.ll index 3fab2dfb41a42..cc000b4c88164 100644 --- a/llvm/test/Transforms/InstCombine/nonnull-select.ll +++ b/llvm/test/Transforms/InstCombine/nonnull-select.ll @@ -5,10 +5,7 @@ define nonnull ptr @pr48975(ptr %.0) { ; CHECK-LABEL: @pr48975( -; CHECK-NEXT: [[DOT1:%.*]] = load ptr, ptr [[DOT0:%.*]], align 8 -; CHECK-NEXT: [[DOT2:%.*]] = icmp eq ptr [[DOT1]], null -; CHECK-NEXT: [[DOT4:%.*]] = select i1 [[DOT2]], ptr null, ptr [[DOT0]] -; CHECK-NEXT: ret ptr [[DOT4]] +; CHECK-NEXT: ret ptr [[DOT4:%.*]] ; %.1 = load ptr, ptr %.0, align 8 %.2 = icmp eq ptr %.1, null @@ -18,8 +15,7 @@ define nonnull ptr @pr48975(ptr %.0) { define nonnull ptr @nonnull_ret(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_ret( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr [[P:%.*]], ptr null -; CHECK-NEXT: ret ptr [[RES]] +; CHECK-NEXT: ret ptr [[RES:%.*]] ; %res = select i1 %cond, ptr %p, ptr null ret ptr %res @@ -27,8 +23,7 @@ define nonnull ptr @nonnull_ret(i1 %cond, ptr %p) { define nonnull ptr @nonnull_ret2(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_ret2( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]] -; CHECK-NEXT: ret ptr [[RES]] +; CHECK-NEXT: ret ptr [[RES:%.*]] ; %res = select i1 %cond, ptr null, ptr %p ret ptr %res @@ -36,8 +31,7 @@ define nonnull ptr @nonnull_ret2(i1 %cond, ptr %p) { define nonnull noundef ptr @nonnull_noundef_ret(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_noundef_ret( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr [[P:%.*]], ptr null -; CHECK-NEXT: ret ptr [[RES]] +; CHECK-NEXT: ret ptr [[RES:%.*]] ; %res = select i1 %cond, ptr %p, ptr null ret ptr %res @@ -45,8 +39,7 @@ define nonnull noundef ptr @nonnull_noundef_ret(i1 %cond, ptr %p) { define nonnull noundef ptr @nonnull_noundef_ret2(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_noundef_ret2( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]] -; CHECK-NEXT: ret ptr [[RES]] +; CHECK-NEXT: ret ptr [[RES:%.*]] ; %res = select i1 %cond, ptr null, ptr %p ret ptr %res @@ -55,8 +48,7 @@ define nonnull noundef ptr @nonnull_noundef_ret2(i1 %cond, ptr %p) { define void @nonnull_call(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_call( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr [[P:%.*]], ptr null -; CHECK-NEXT: call void @f(ptr nonnull [[RES]]) +; CHECK-NEXT: call void @f(ptr nonnull [[RES:%.*]]) ; CHECK-NEXT: ret void ; %res = select i1 %cond, ptr %p, ptr null @@ -66,8 +58,7 @@ define void @nonnull_call(i1 %cond, ptr %p) { define void @nonnull_call2(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_call2( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]] -; CHECK-NEXT: call void @f(ptr nonnull [[RES]]) +; CHECK-NEXT: call void @f(ptr nonnull [[RES:%.*]]) ; CHECK-NEXT: ret void ; %res = select i1 %cond, ptr null, ptr %p @@ -77,8 +68,7 @@ define void @nonnull_call2(i1 %cond, ptr %p) { define void @nonnull_noundef_call(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_noundef_call( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr [[P:%.*]], ptr null -; CHECK-NEXT: call void @f(ptr noundef nonnull [[RES]]) +; CHECK-NEXT: call void @f(ptr noundef nonnull [[RES:%.*]]) ; CHECK-NEXT: ret void ; %res = select i1 %cond, ptr %p, ptr null @@ -88,8 +78,7 @@ define void @nonnull_noundef_call(i1 %cond, ptr %p) { define void @nonnull_noundef_call2(i1 %cond, ptr %p) { ; CHECK-LABEL: @nonnull_noundef_call2( -; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND:%.*]], ptr null, ptr [[P:%.*]] -; CHECK-NEXT: call void @f(ptr noundef nonnull [[RES]]) +; CHECK-NEXT: call void @f(ptr noundef nonnull [[RES:%.*]]) ; CHECK-NEXT: ret void ; %res = select i1 %cond, ptr null, ptr %p diff --git a/llvm/test/Transforms/PhaseOrdering/load-store-sameval.ll b/llvm/test/Transforms/PhaseOrdering/load-store-sameval.ll index d8ef0723cf09e..f6bf57a678786 100644 --- a/llvm/test/Transforms/PhaseOrdering/load-store-sameval.ll +++ b/llvm/test/Transforms/PhaseOrdering/load-store-sameval.ll @@ -1,24 +1,21 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt -passes='instcombine,early-cse' -S %s | FileCheck %s -; FIXME: We can remove the store instruction in the exit block define i32 @load_store_sameval(ptr %p, i1 %cond1, i1 %cond2) { ; CHECK-LABEL: define i32 @load_store_sameval( ; CHECK-SAME: ptr [[P:%.*]], i1 [[COND1:%.*]], i1 [[COND2:%.*]]) { ; CHECK-NEXT: [[ENTRY:.*:]] -; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[COND1]], ptr null, ptr [[P]] -; CHECK-NEXT: [[PRE:%.*]] = load i32, ptr [[SPEC_SELECT]], align 4 +; CHECK-NEXT: [[PRE:%.*]] = load i32, ptr [[P]], align 4 ; CHECK-NEXT: br label %[[BLOCK:.*]] ; CHECK: [[BLOCK]]: ; CHECK-NEXT: br label %[[BLOCK2:.*]] ; CHECK: [[BLOCK2]]: ; CHECK-NEXT: br i1 [[COND2]], label %[[BLOCK3:.*]], label %[[EXIT:.*]] ; CHECK: [[BLOCK3]]: -; CHECK-NEXT: [[LOAD:%.*]] = load double, ptr [[SPEC_SELECT]], align 8 +; CHECK-NEXT: [[LOAD:%.*]] = load double, ptr [[P]], align 8 ; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[LOAD]], 0.000000e+00 ; CHECK-NEXT: br i1 [[CMP]], label %[[BLOCK]], label %[[BLOCK2]] ; CHECK: [[EXIT]]: -; CHECK-NEXT: store i32 [[PRE]], ptr [[P]], align 4 ; CHECK-NEXT: ret i32 0 ; entry: diff --git a/llvm/test/Transforms/PhaseOrdering/memset-combine.ll b/llvm/test/Transforms/PhaseOrdering/memset-combine.ll index b7afa4121caef..d1de11258ed91 100644 --- a/llvm/test/Transforms/PhaseOrdering/memset-combine.ll +++ b/llvm/test/Transforms/PhaseOrdering/memset-combine.ll @@ -7,8 +7,9 @@ define void @merge_memset(ptr %p, i1 %cond) { ; CHECK-LABEL: define void @merge_memset( ; CHECK-SAME: ptr [[P:%.*]], i1 [[COND:%.*]]) { ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], ptr null, ptr [[P]] +; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(4096) [[P]], i8 0, i64 4096, i1 false) ; CHECK-NEXT: [[OFF:%.*]] = getelementptr inbounds nuw i8, ptr [[SEL]], i64 4096 -; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[SEL]], i8 0, i64 4864, i1 false) +; CHECK-NEXT: tail call void @llvm.memset.p0.i64(ptr noundef nonnull align 1 dereferenceable(768) [[OFF]], i8 0, i64 768, i1 false) ; CHECK-NEXT: ret void ; %sel = select i1 %cond, ptr null, ptr %p From f21b72c4d97fce962afeb090dcb7ac0209ac19cd Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 22 Feb 2025 00:48:04 +0800 Subject: [PATCH 4/6] Revert "[IR] Add a helper `Function::isReturnNonNull`" This reverts commit b4cac6ad69dbe66bc86b7e0a9cd6eea7c62c161f. --- llvm/include/llvm/IR/Function.h | 5 ----- llvm/lib/IR/Function.cpp | 11 ----------- 2 files changed, 16 deletions(-) diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index 7ea8673bedad1..29041688124bc 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -731,11 +731,6 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node { /// create a Function) from the Function Src to this one. void copyAttributesFrom(const Function *Src); - /// Return true if the return value is known to be not null. - /// This may be because it has the nonnull attribute, or because at least - /// one byte is dereferenceable and the pointer is in addrspace(0). - bool isReturnNonNull() const; - /// deleteBody - This method deletes the body of the function, and converts /// the linkage to external. /// diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp index d22cf65769e26..5666f0a53866f 100644 --- a/llvm/lib/IR/Function.cpp +++ b/llvm/lib/IR/Function.cpp @@ -873,17 +873,6 @@ void Function::copyAttributesFrom(const Function *Src) { setPrologueData(Src->getPrologueData()); } -bool Function::isReturnNonNull() const { - if (hasRetAttribute(Attribute::NonNull)) - return true; - - if (AttributeSets.getRetDereferenceableBytes() > 0 && - !NullPointerIsDefined(this, getReturnType()->getPointerAddressSpace())) - return true; - - return false; -} - MemoryEffects Function::getMemoryEffects() const { return getAttributes().getMemoryEffects(); } From 1a5f3fbdc67e3ca430dec64fd92e964f0fab02d2 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 22 Feb 2025 00:50:20 +0800 Subject: [PATCH 5/6] [InstCombine] Remove use of `Function::isReturnNonNull` --- .../InstCombine/InstructionCombining.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index d3af06f63fcd2..b7748f59a0cfc 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3590,15 +3590,20 @@ Instruction *InstCombinerImpl::visitReturnInst(ReturnInst &RI) { if (!RetVal) return nullptr; - if (RetVal->getType()->isPointerTy() && RI.getFunction()->isReturnNonNull()) { - if (Value *V = simplifyNonNullOperand(RetVal)) - return replaceOperand(RI, 0, V); + Function *F = RI.getFunction(); + Type *RetTy = RetVal->getType(); + if (RetTy->isPointerTy()) { + if (F->hasRetAttribute(Attribute::NonNull) || + (F->getAttributes().getRetDereferenceableBytes() > 0 && + !NullPointerIsDefined(F, RetTy->getPointerAddressSpace()))) { + if (Value *V = simplifyNonNullOperand(RetVal)) + return replaceOperand(RI, 0, V); + } } - if (!AttributeFuncs::isNoFPClassCompatibleType(RetVal->getType())) + if (!AttributeFuncs::isNoFPClassCompatibleType(RetTy)) return nullptr; - Function *F = RI.getFunction(); FPClassTest ReturnClass = F->getAttributes().getRetNoFPClass(); if (ReturnClass == fcNone) return nullptr; From 0ff99b1f3c13b5b1688308aa7e344ae84d7ec28f Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 22 Feb 2025 01:13:45 +0800 Subject: [PATCH 6/6] [InstCombine] Address review comments. --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index c8b3d29c3aa98..54f777ab20a7a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3994,18 +3994,17 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) { for (Value *V : Call.args()) { if (V->getType()->isPointerTy()) { - // Simplify the nonnull operand before nonnull inference to avoid - // unnecessary queries. + // Simplify the nonnull operand if the parameter is known to be nonnull. + // Otherwise, try to infer nonnull for it. if (Call.paramHasNonNullAttr(ArgNo, /*AllowUndefOrPoison=*/true)) { if (Value *Res = simplifyNonNullOperand(V)) { replaceOperand(Call, ArgNo, Res); Changed = true; } - } - - if (!Call.paramHasAttr(ArgNo, Attribute::NonNull) && - isKnownNonZero(V, getSimplifyQuery().getWithInstruction(&Call))) + } else if (isKnownNonZero(V, + getSimplifyQuery().getWithInstruction(&Call))) { ArgNos.push_back(ArgNo); + } } ArgNo++; }