[llvm] [SimplifyCFG] Bail out on vector GEPs in `passingValueIsAlwaysUndefined` (PR #142526)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 3 09:21:35 PDT 2025


https://github.com/dtcxzyw updated https://github.com/llvm/llvm-project/pull/142526

>From a9f51cb341c8f7383faa4120f55687ebf39170d3 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
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<Constant>(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<VectorType>(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 <dtcxzyw2333 at gmail.com>
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<GetElementPtrInst>(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<VectorType>(GEP->getType())->getElementCount(), C);
         return passingValueIsAlwaysUndefined(V, GEP, PtrValueMayBeModified);
       }
 



More information about the llvm-commits mailing list