This is a follow on for D111675 which implements the gep case. I'd originally left it out because I was hoping to actually implement the inrange todo, but after a bit of staring at the code, decided to leave it as is since it doesn't effect this use case (i.e. instcombine requires the op to freeze to be an instruction).
Differential Revision: https://reviews.llvm.org/D111691
if (const auto *ExactOp = dyn_cast<PossiblyExactOperator>(Op))
if (ExactOp->isExact())
return true;
+ if (const auto *GEP = dyn_cast<GEPOperator>(Op))
+ if (GEP->isInBounds())
+ return true;
}
// TODO: this should really be under the ConsiderFlags block, but currently
case Instruction::ICmp:
case Instruction::FCmp:
return false;
- case Instruction::GetElementPtr: {
- const auto *GEP = cast<GEPOperator>(Op);
- return GEP->isInBounds();
- }
+ case Instruction::GetElementPtr:
+ // inbounds is handled above
+ // TODO: what about inrange on constexpr?
+ return false;
default: {
const auto *CE = dyn_cast<ConstantExpr>(Op);
if (isa<CastInst>(Op) || (CE && CE->isCast()))
define i8* @propagate_drop_gep1(i8* %arg) {
; CHECK-LABEL: @propagate_drop_gep1(
-; CHECK-NEXT: [[V1:%.*]] = getelementptr inbounds i8, i8* [[ARG:%.*]], i64 16
-; CHECK-NEXT: [[V1_FR:%.*]] = freeze i8* [[V1]]
-; CHECK-NEXT: ret i8* [[V1_FR]]
+; CHECK-NEXT: [[ARG_FR:%.*]] = freeze i8* [[ARG:%.*]]
+; CHECK-NEXT: [[V1:%.*]] = getelementptr i8, i8* [[ARG_FR]], i64 16
+; CHECK-NEXT: ret i8* [[V1]]
;
%v1 = getelementptr inbounds i8, i8* %arg, i64 16
%v1.fr = freeze i8* %v1