diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index b7299e01b0c5f..d6be5089bbb47 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; @@ -8166,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 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()