Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -959,6 +959,16 @@ return nullptr; } +static bool canSimplifyNullStoreOrGEP(StoreInst &SI) { + if (SI.getPointerAddressSpace() != 0) + return false; + + auto *Ptr = SI.getPointerOperand(); + if (GetElementPtrInst *GEPI = dyn_cast(Ptr)) + Ptr = GEPI->getOperand(0); + return isa(Ptr); +} + static bool canSimplifyNullLoadOrGEP(LoadInst &LI, Value *Op) { if (GetElementPtrInst *GEPI = dyn_cast(Op)) { const Value *GEPI0 = GEPI->getOperand(0); @@ -1447,7 +1457,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: llvm/trunk/test/Transforms/InstCombine/store.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/store.ll +++ llvm/trunk/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"