diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index b62f6e20496..2f608b26acc 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -571,6 +571,14 @@ static Value *EvaluateGEPOffsetExpression(User *GEP, InstCombiner &IC) { Instruction *InstCombiner::FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS, ICmpInst::Predicate Cond, Instruction &I) { + // Don't transform signed compares of GEPs into index compares. Even if the + // GEP is inbounds, the final add of the base pointer can have signed overflow + // and would change the result of the icmp. + // e.g. "&foo[0] (RHS)) RHS = BCI->getOperand(0); diff --git a/test/Transforms/InstCombine/icmp.ll b/test/Transforms/InstCombine/icmp.ll index 8c4871942cb..dabb0f3adfe 100644 --- a/test/Transforms/InstCombine/icmp.ll +++ b/test/Transforms/InstCombine/icmp.ll @@ -628,3 +628,14 @@ define i1 @test61(i8* %foo, i64 %i, i64 %j) { ; CHECK: icmp ult i8* %cast1, %gep2 ; CHECK-NEXT: ret i1 } + +define i1 @test62(i8* %a) { + %arrayidx1 = getelementptr inbounds i8* %a, i64 1 + %arrayidx2 = getelementptr inbounds i8* %a, i64 10 + %cmp = icmp slt i8* %arrayidx1, %arrayidx2 + ret i1 %cmp +; Don't turn a signed cmp of GEPs into an index compare. +; CHECK: @test62 +; CHECK: %cmp = icmp slt i8* %arrayidx1, %arrayidx2 +; CHECK-NEXT: ret i1 %cmp +}