[llvm] EarlyCSE: create casts on type-mismatch (PR #113339)

Ramkumar Ramachandra via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 4 05:29:38 PST 2024


================
@@ -964,32 +965,39 @@ class EarlyCSE {
   bool overridingStores(const ParseMemoryInst &Earlier,
                         const ParseMemoryInst &Later);
 
-  Value *getOrCreateResult(Value *Inst, Type *ExpectedType) const {
-    // TODO: We could insert relevant casts on type mismatch here.
-    if (auto *LI = dyn_cast<LoadInst>(Inst))
-      return LI->getType() == ExpectedType ? LI : nullptr;
-    if (auto *SI = dyn_cast<StoreInst>(Inst)) {
-      Value *V = SI->getValueOperand();
-      return V->getType() == ExpectedType ? V : nullptr;
+  Value *getOrCreateResult(Instruction *Inst, Type *ExpectedType) const {
+    // The load or the store's first operand.
+    Value *V;
+    if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
+      switch (II->getIntrinsicID()) {
+      case Intrinsic::masked_load:
+        V = II;
+        break;
+      case Intrinsic::masked_store:
+        V = II->getOperand(0);
+        break;
+      default:
+        return TTI.getOrCreateResultFromMemIntrinsic(II, ExpectedType);
+      }
+    } else {
+      V = isa<LoadInst>(Inst) ? Inst : cast<StoreInst>(Inst)->getValueOperand();
     }
-    assert(isa<IntrinsicInst>(Inst) && "Instruction not supported");
-    auto *II = cast<IntrinsicInst>(Inst);
-    if (isHandledNonTargetIntrinsic(II->getIntrinsicID()))
-      return getOrCreateResultNonTargetMemIntrinsic(II, ExpectedType);
-    return TTI.getOrCreateResultFromMemIntrinsic(II, ExpectedType);
-  }
 
-  Value *getOrCreateResultNonTargetMemIntrinsic(IntrinsicInst *II,
-                                                Type *ExpectedType) const {
-    // TODO: We could insert relevant casts on type mismatch here.
-    switch (II->getIntrinsicID()) {
-    case Intrinsic::masked_load:
-      return II->getType() == ExpectedType ? II : nullptr;
-    case Intrinsic::masked_store: {
-      Value *V = II->getOperand(0);
-      return V->getType() == ExpectedType ? V : nullptr;
-    }
-    }
+    Type *ActualType = V->getType();
+    BasicBlock *TheBB = Inst->getParent();
+
+    // First handle the case when no cast is required.
+    if (ActualType == ExpectedType)
+      return V;
+
+    // Try to create BitCast, SExt, or Trunc.
+    IRBuilder<> Builder(TheBB, std::next(Inst->getIterator()));
+    if (CastInst::castIsValid(Instruction::BitCast, V, ExpectedType))
+      return Builder.CreateBitCast(V, ExpectedType);
+    if (CastInst::castIsValid(Instruction::SExt, V, ExpectedType))
+      return Builder.CreateSExt(V, ExpectedType);
----------------
artagnon wrote:

I had  my doubts about this part too; thanks for sanity-checking: will drop the sext and trunc.

https://github.com/llvm/llvm-project/pull/113339


More information about the llvm-commits mailing list