[llvm] [clang] split load to bytes to deduce load value (PR #72364)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 15 02:31:39 PST 2023


================
@@ -2128,6 +2129,105 @@ static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl) {
   I->replaceAllUsesWith(Repl);
 }
 
+// split load to single byte loads and check if the value can be deduced
+//
+// Example:
+// define i32 @f(i8* %P)
+// 1:  %b2 = getelementptr inbounds i8, i8* %P, i64 1
+// 2:  store i8 0, i8* %b2, align 1
+// 3:  store i8 0, i8* %P, align 1
+// 4:  %s1 = bitcast i8* %P to i16*
+// 5:  %L = load i16, i16* %s1, align 4
+//
+// The last clobbering write for the load is (3) but it doesn't cover the whole
+// read. So AnalyzeLoadAvailability would give up.
+// This function emit temporary byte-sized loads that cover the original load,
+// so that any last write covers the read. We run AnalyzeLoadAvailability on
+// each byte to try to construct the load as a constant.
+bool GVNPass::splitAndprocessLoad(LoadInst *L) {
+  if (L->isAtomic())
+    return false;
+
+  Type *LTy = L->getType();
+  if (!LTy->isIntegerTy())
+    return false;
+
+  unsigned BW = LTy->getIntegerBitWidth();
+  if (BW % 8)
+    return false;
+
+  IntegerType *ByteTy = IntegerType::getInt8Ty(LTy->getContext());
+  Type *BytePtrTy = PointerType::get(ByteTy, L->getPointerAddressSpace());
+  BitCastInst *Base = new BitCastInst(L->getPointerOperand(), BytePtrTy, "", L);
----------------
nikic wrote:

Not necessary with opaque pointers.

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


More information about the llvm-commits mailing list