From a9f51cb341c8f7383faa4120f55687ebf39170d3 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Tue, 3 Jun 2025 11:13:45 +0800 Subject: [PATCH 1/2] [SimplifyCFG] Handle vector GEP in `passingValueIsAlwaysUndefined` --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 5 +++++ .../SimplifyCFG/UnreachableEliminate.ll | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index b7299e01b0c5f..898ff3d1f8f12 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -8109,6 +8109,7 @@ bool SimplifyCFGOpt::simplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) { /// Check if passing a value to an instruction will cause undefined behavior. static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValueMayBeModified) { + assert(V->getType() == I->getType() && "Mismatched types"); Constant *C = dyn_cast(V); if (!C) return false; @@ -8177,6 +8178,10 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu NullPointerIsDefined(GEP->getFunction(), GEP->getPointerAddressSpace()))) PtrValueMayBeModified = true; + // The type of GEP may differ from the type of base pointer. + if (V->getType() != GEP->getType()) + V = ConstantVector::getSplat( + cast(GEP->getType())->getElementCount(), C); return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified); } diff --git a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll index 2da5d18b63f49..5b439a23c3585 100644 --- a/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll +++ b/llvm/test/Transforms/SimplifyCFG/UnreachableEliminate.ll @@ -244,6 +244,7 @@ declare ptr @fn_nonnull_arg(ptr nonnull %p) declare ptr @fn_noundef_arg(ptr noundef %p) declare ptr @fn_ptr_arg(ptr) declare ptr @fn_ptr_arg_nounwind_willreturn(ptr) nounwind willreturn +declare void @fn_arg_vec(<2 x ptr>) define void @test9(i1 %X, ptr %Y) { ; CHECK-LABEL: @test9( @@ -917,6 +918,25 @@ bb5: ; preds = %bb3, %bb ret i32 %i7 } +define void @test9_gep_splat(i1 %X, ptr %Y) { +; CHECK-LABEL: @test9_gep_splat( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[X:%.*]], ptr null, ptr [[Y:%.*]] +; CHECK-NEXT: [[GEP:%.*]] = getelementptr i8, ptr [[SPEC_SELECT]], <2 x i64> zeroinitializer +; CHECK-NEXT: call void @fn_arg_vec(<2 x ptr> [[GEP]]) +; CHECK-NEXT: ret void +; +entry: + br i1 %X, label %if, label %else +if: + br label %else +else: + %phi = phi ptr [ %Y, %entry ], [ null, %if ] + %gep = getelementptr i8, ptr %phi, <2 x i64> zeroinitializer + call void @fn_arg_vec(<2 x ptr> %gep) + ret void +} + declare void @side.effect() declare i8 @get.i8() From 37b60e44c6fd9c0be4d8b35842c7543bae3e2e58 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Wed, 4 Jun 2025 00:21:12 +0800 Subject: [PATCH 2/2] [InstCombine] Address review comments. --- llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 898ff3d1f8f12..d6be5089bbb47 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -8167,6 +8167,10 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu // Look through GEPs. A load from a GEP derived from NULL is still undefined if (GetElementPtrInst *GEP = dyn_cast(User)) if (GEP->getPointerOperand() == I) { + // The type of GEP may differ from the type of base pointer. + // Bail out on vector GEPs, as they are not handled by other checks. + if (GEP->getType()->isVectorTy()) + return false; // The current base address is null, there are four cases to consider: // getelementptr (TY, null, 0) -> null // getelementptr (TY, null, not zero) -> may be modified @@ -8178,10 +8182,6 @@ static bool passingValueIsAlwaysUndefined(Value *V, Instruction *I, bool PtrValu NullPointerIsDefined(GEP->getFunction(), GEP->getPointerAddressSpace()))) PtrValueMayBeModified = true; - // The type of GEP may differ from the type of base pointer. - if (V->getType() != GEP->getType()) - V = ConstantVector::getSplat( - cast(GEP->getType())->getElementCount(), C); return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified); }