[instcombine] propagate single use freeze(gep inbounds X)
authorPhilip Reames <listmail@philipreames.com>
Wed, 13 Oct 2021 16:23:47 +0000 (09:23 -0700)
committerPhilip Reames <listmail@philipreames.com>
Wed, 13 Oct 2021 16:25:00 +0000 (09:25 -0700)
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

llvm/lib/Analysis/ValueTracking.cpp
llvm/test/Transforms/InstCombine/freeze.ll

index ece7c88..cce1e88 100644 (file)
@@ -4959,6 +4959,9 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
     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
@@ -5051,10 +5054,10 @@ static bool canCreateUndefOrPoison(const Operator *Op, bool PoisonOnly,
   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()))
index 03f1248..e05951d 100644 (file)
@@ -354,9 +354,9 @@ define i32 @propagate_drop_lshr2(i32 %arg, i32 %unknown) {
 
 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