Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -3400,6 +3400,8 @@ std::swap(NewT, NewF); Value *NewSI = Builder.CreateSelect(CondVal, NewT, NewF, SI.getName() + ".idx", &SI); + if (Gep->isInBounds()) + return GetElementPtrInst::CreateInBounds(ElementType, Ptr, {NewSI}); return GetElementPtrInst::Create(ElementType, Ptr, {NewSI}); }; if (auto *TrueGep = dyn_cast(TrueVal)) Index: llvm/test/Transforms/InstCombine/select-gep.ll =================================================================== --- llvm/test/Transforms/InstCombine/select-gep.ll +++ llvm/test/Transforms/InstCombine/select-gep.ll @@ -75,7 +75,7 @@ ; CHECK-LABEL: @test2a( ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: [[SELECT_IDX:%.*]] = select i1 [[CMP]], i64 [[X]], i64 0 -; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[SELECT_IDX]] +; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[SELECT_IDX]] ; CHECK-NEXT: ret ptr [[SELECT]] ; %gep = getelementptr inbounds i32, ptr %p, i64 %x @@ -89,7 +89,7 @@ ; CHECK-LABEL: @test2b( ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i64 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: [[SELECT_IDX:%.*]] = select i1 [[CMP]], i64 0, i64 [[X]] -; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 [[SELECT_IDX]] +; CHECK-NEXT: [[SELECT:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[SELECT_IDX]] ; CHECK-NEXT: ret ptr [[SELECT]] ; %gep = getelementptr inbounds i32, ptr %p, i64 %x @@ -104,7 +104,7 @@ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]] ; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]] ; CHECK-NEXT: [[SEL_IDX:%.*]] = select i1 [[ICMP]], i64 0, i64 6 -; CHECK-NEXT: [[SEL:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[SEL_IDX]] +; CHECK-NEXT: [[SEL:%.*]] = getelementptr inbounds i32, ptr [[GEP1]], i64 [[SEL_IDX]] ; CHECK-NEXT: ret ptr [[SEL]] ; %gep1 = getelementptr inbounds i32, ptr %p, i64 %x @@ -120,7 +120,7 @@ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]] ; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]] ; CHECK-NEXT: [[SEL_IDX:%.*]] = select i1 [[ICMP]], i64 6, i64 0 -; CHECK-NEXT: [[SEL:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[SEL_IDX]] +; CHECK-NEXT: [[SEL:%.*]] = getelementptr inbounds i32, ptr [[GEP1]], i64 [[SEL_IDX]] ; CHECK-NEXT: ret ptr [[SEL]] ; %gep1 = getelementptr inbounds i32, ptr %p, i64 %x @@ -231,7 +231,7 @@ ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 [[X:%.*]] ; CHECK-NEXT: [[ICMP:%.*]] = icmp ugt i64 [[X]], [[Y:%.*]] ; CHECK-NEXT: [[SEL_IDX:%.*]] = select i1 [[ICMP]], i64 [[Y]], i64 0 -; CHECK-NEXT: [[SEL:%.*]] = getelementptr i32, ptr [[GEP1]], i64 [[SEL_IDX]] +; CHECK-NEXT: [[SEL:%.*]] = getelementptr inbounds i32, ptr [[GEP1]], i64 [[SEL_IDX]] ; CHECK-NEXT: call void @use_i32p(ptr [[GEP1]]) ; CHECK-NEXT: ret ptr [[SEL]] ; Index: llvm/test/Transforms/InstCombine/stpncpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/stpncpy-1.ll +++ llvm/test/Transforms/InstCombine/stpncpy-1.ll @@ -47,8 +47,8 @@ ; ANY-NEXT: [[STXNCPY_CHAR0:%.*]] = load i8, ptr [[DST]], align 1 ; ANY-NEXT: [[STPNCPY_CHAR0CMP:%.*]] = icmp ne i8 [[STXNCPY_CHAR0]], 0 ; ANY-NEXT: [[STPNCPY_SEL_IDX:%.*]] = zext i1 [[STPNCPY_CHAR0CMP]] to i64 -; ANY-NEXT: [[STPNCPY_SEL:%.*]] = getelementptr i8, ptr [[DST]], i64 [[STPNCPY_SEL_IDX]] -; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr [[STPNCPY_SEL]]) +; ANY-NEXT: [[STPNCPY_SEL:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[STPNCPY_SEL_IDX]] +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_SEL]]) ; ANY-NEXT: ret void ; ; Fold stpncpy(D, D, 0) to just D. @@ -398,8 +398,8 @@ ; ANY-NEXT: store i8 [[STXNCPY_CHAR0]], ptr [[DST]], align 1 ; ANY-NEXT: [[STPNCPY_CHAR0CMP:%.*]] = icmp ne i8 [[STXNCPY_CHAR0]], 0 ; ANY-NEXT: [[STPNCPY_SEL_IDX:%.*]] = zext i1 [[STPNCPY_CHAR0CMP]] to i64 -; ANY-NEXT: [[STPNCPY_SEL:%.*]] = getelementptr i8, ptr [[DST]], i64 [[STPNCPY_SEL_IDX]] -; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr [[STPNCPY_SEL]]) +; ANY-NEXT: [[STPNCPY_SEL:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 [[STPNCPY_SEL_IDX]] +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_SEL]]) ; ANY-NEXT: ret void ; ; Fold stpncpy(D, S, 0) to just D. Index: llvm/test/Transforms/PhaseOrdering/gep-null-compare-in-loop.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/gep-null-compare-in-loop.ll +++ llvm/test/Transforms/PhaseOrdering/gep-null-compare-in-loop.ll @@ -52,28 +52,9 @@ define i32 @using_malloc() { ; CHECK-LABEL: define i32 @using_malloc -; CHECK-SAME: () local_unnamed_addr #[[ATTR1:[0-9]+]] { +; CHECK-SAME: () local_unnamed_addr #[[ATTR0]] { ; CHECK-NEXT: bb: -; CHECK-NEXT: [[ALLOC:%.*]] = tail call dereferenceable_or_null(64) ptr @malloc(i64 64) -; CHECK-NEXT: store i32 1, ptr [[ALLOC]], align 4 -; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr i32, ptr [[ALLOC]], i64 1 -; CHECK-NEXT: store i32 2, ptr [[GETELEMENTPTR]], align 4 -; CHECK-NEXT: [[GETELEMENTPTR1:%.*]] = getelementptr i32, ptr [[ALLOC]], i64 2 -; CHECK-NEXT: store i32 3, ptr [[GETELEMENTPTR1]], align 4 -; CHECK-NEXT: [[GETELEMENTPTR2:%.*]] = getelementptr i32, ptr [[ALLOC]], i64 3 -; CHECK-NEXT: br label [[BB11_I:%.*]] -; CHECK: bb11.i: -; CHECK-NEXT: [[PHI37_I:%.*]] = phi i32 [ [[ADD_I:%.*]], [[BB11_I]] ], [ 0, [[BB:%.*]] ] -; CHECK-NEXT: [[PHI6_I:%.*]] = phi ptr [ [[SPEC_SELECT_I:%.*]], [[BB11_I]] ], [ [[ALLOC]], [[BB]] ] -; CHECK-NEXT: [[SPEC_SELECT_I]] = getelementptr i32, ptr [[PHI6_I]], i64 1 -; CHECK-NEXT: [[LOAD_I:%.*]] = load i32, ptr [[PHI6_I]], align 4 -; CHECK-NEXT: [[ADD_I]] = add i32 [[LOAD_I]], [[PHI37_I]] -; CHECK-NEXT: [[ICMP4_I:%.*]] = icmp ne ptr [[SPEC_SELECT_I]], [[GETELEMENTPTR2]] -; CHECK-NEXT: [[ICMP102_I:%.*]] = icmp ne ptr [[SPEC_SELECT_I]], null -; CHECK-NEXT: [[ICMP10_NOT_I:%.*]] = and i1 [[ICMP102_I]], [[ICMP4_I]] -; CHECK-NEXT: br i1 [[ICMP10_NOT_I]], label [[BB11_I]], label [[LOOP_EXIT:%.*]] -; CHECK: loop.exit: -; CHECK-NEXT: ret i32 [[ADD_I]] +; CHECK-NEXT: ret i32 6 ; bb: %alloc = call dereferenceable_or_null(64) ptr @malloc(i64 64)