[PATCH] D101103: [InstSimplify] Treat invariant group insts as bitcasts for load operands

Arthur Eubanks via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 22 13:14:42 PDT 2021


aeubanks created this revision.
aeubanks added reviewers: rnk, pcc, nikic.
Herald added subscribers: hiraditya, Prazek.
aeubanks requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

We can look through invariant group intrinsics for the purposes of
simplifying the result of a load.

Since intrinsics can't be constants, but we also don't want to
completely rewrite load constant folding, we convert the load operand to
a constant. For GEPs and bitcasts we just treat them as constants. For
invariant group intrinsics, we treat them as a bitcast.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101103

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstSimplify/invariant.group-load.ll


Index: llvm/test/Transforms/InstSimplify/invariant.group-load.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstSimplify/invariant.group-load.ll
@@ -0,0 +1,18 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
+
+ at A = linkonce_odr hidden constant { i64, i64 } { i64 2, i64 3 }
+
+declare i8* @llvm.strip.invariant.group.p0i8(i8* %p)
+
+define i64 @f() {
+; CHECK-LABEL: @f(
+; CHECK-NEXT:    ret i64 3
+;
+  %p = bitcast { i64, i64 }* @A to i8*
+  %a = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
+  %b = getelementptr i8, i8* %a, i32 8
+  %c = bitcast i8* %b to i64*
+  %d = load i64, i64* %c
+  ret i64 %d
+}
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -5852,6 +5852,54 @@
   return ::SimplifyFreezeInst(Op0, Q);
 }
 
+static Constant *ConstructLoadOperandConstant(Value *Op) {
+  if (auto *C = dyn_cast<Constant>(Op))
+    return C;
+
+  if (auto *BC = dyn_cast<BitCastOperator>(Op)) {
+    if (auto *C = ConstructLoadOperandConstant(BC->getOperand(0))) {
+      return ConstantExpr::getBitCast(C, BC->getType());
+    }
+    return nullptr;
+  }
+  if (auto *GEP = dyn_cast<GEPOperator>(Op)) {
+    if (auto *C = ConstructLoadOperandConstant(GEP->getPointerOperand())) {
+      SmallVector<Constant *> Idxs;
+      for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I) {
+        if (auto *Idx = dyn_cast<Constant>(GEP->getOperand(I)))
+          Idxs.push_back(Idx);
+        else
+          return nullptr;
+      }
+      return ConstantExpr::getGetElementPtr(GEP->getSourceElementType(), C,
+                                            Idxs, GEP->isInBounds(),
+                                            GEP->getInRangeIndex());
+    }
+    return nullptr;
+  }
+  if (auto *II = dyn_cast<IntrinsicInst>(Op)) {
+    if (II->getIntrinsicID() == Intrinsic::strip_invariant_group ||
+        II->getIntrinsicID() == Intrinsic::launder_invariant_group) {
+      if (auto *C = ConstructLoadOperandConstant(II->getOperand(0))) {
+        return ConstantExpr::getBitCast(C, II->getType());
+      }
+    }
+    return nullptr;
+  }
+  return nullptr;
+}
+
+static Value *SimplifyLoadInst(LoadInst *LI, const SimplifyQuery &Q) {
+  if (auto *C = dyn_cast<Constant>(LI->getPointerOperand()))
+    return ConstantFoldLoadFromConstPtr(C, LI->getType(), Q.DL);
+
+  if (auto *C = dyn_cast_or_null<Constant>(
+          ConstructLoadOperandConstant(LI->getPointerOperand())))
+    return ConstantFoldLoadFromConstPtr(C, LI->getType(), Q.DL);
+
+  return nullptr;
+}
+
 /// See if we can compute a simplified version of this instruction.
 /// If not, this returns null.
 
@@ -6008,6 +6056,9 @@
     // No simplifications for Alloca and it can't be constant folded.
     Result = nullptr;
     break;
+  case Instruction::Load:
+    Result = SimplifyLoadInst(cast<LoadInst>(I), Q);
+    break;
   }
 
   /// If called on unreachable code, the above logic may report that the


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101103.339765.patch
Type: text/x-patch
Size: 3198 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210422/b35aaa3e/attachment.bin>


More information about the llvm-commits mailing list