Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -931,6 +931,18 @@ return nullptr; } +static bool canSimplifyNullStoreOrGEP(StoreInst &SI) { + auto *Ptr = SI.getPointerOperand(); + if (GetElementPtrInst *GEPI = dyn_cast(Ptr)) { + const Value *GEPI0 = GEPI->getOperand(0); + if (isa(GEPI0) && GEPI->getPointerAddressSpace() == 0) + return true; + } + if (isa(Ptr) && SI.getPointerAddressSpace() == 0) + return true; + return false; +} + static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) { if (GetElementPtrInst *GEPI = dyn_cast(Op)) { const Value *GEPI0 = GEPI->getOperand(0); @@ -1392,7 +1404,8 @@ } // store X, null -> turns into 'unreachable' in SimplifyCFG - if (isa(Ptr) && SI.getPointerAddressSpace() == 0) { + // store X, GEP(null, Y) -> turns into 'unreachable' in SimplifyCFG + if (canSimplifyNullStoreOrGEP(SI)) { if (!isa(Val)) { SI.setOperand(0, UndefValue::get(Val->getType())); if (Instruction *U = dyn_cast(Val)) Index: test/Transforms/InstCombine/store.ll =================================================================== --- test/Transforms/InstCombine/store.ll +++ test/Transforms/InstCombine/store.ll @@ -20,6 +20,14 @@ ; CHECK-NEXT: ret void } +define void @store_at_gep_off_null(i64 %offset) { +; CHECK-LABEL: @store_at_gep_off_null +; CHECK: store i32 undef, i32* %ptr + %ptr = getelementptr i32, i32 *null, i64 %offset + store i32 24, i32* %ptr + ret void +} + ;; Simple sinking tests ; "if then else"