[llvm] [LICM] Prevent LICM of ptrtoint and inttoptr when using non-integral pointers (PR #97272)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 1 02:52:14 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Csanád Hajdú (Il-Capitano)

<details>
<summary>Changes</summary>

Non-integral pointers don't have a stable bit representation, i.e. subsequent executions of `ptrtoint` or `inttoptr` instructions can create different results, therefore it is invalid to move these instructions outside of a loop when they use non-integral pointer types.

---
Full diff: https://github.com/llvm/llvm-project/pull/97272.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Scalar/LICM.cpp (+15) 
- (added) llvm/test/Transforms/LICM/non-integral-pointers.ll (+67) 


``````````diff
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 91ef2b4b7c183..f286d910f932e 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -70,6 +70,7 @@
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Metadata.h"
+#include "llvm/IR/Module.h"
 #include "llvm/IR/PatternMatch.h"
 #include "llvm/IR/PredIteratorCache.h"
 #include "llvm/InitializePasses.h"
@@ -1328,6 +1329,20 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
           }
       }
     return true;
+  } else if (auto *PTII = dyn_cast<PtrToIntInst>(&I)) {
+    const DataLayout &DL = I.getModule()->getDataLayout();
+    // Non-integral pointers may not have a stable bit representation, therefore
+    // casting them to an integer is not loop invariant.
+    if (DL.isNonIntegralPointerType(PTII->getPointerOperand()->getType())) {
+      return false;
+    }
+  } else if (auto *ITPI = dyn_cast<IntToPtrInst>(&I)) {
+    const DataLayout &DL = I.getModule()->getDataLayout();
+    // Non-integral pointers may not have a stable bit representation, therefore
+    // casting an integer to a non-integral pointer type is not loop invariant.
+    if (DL.isNonIntegralPointerType(ITPI->getType())) {
+      return false;
+    }
   }
 
   assert(!I.mayReadOrWriteMemory() && "unhandled aliasing");
diff --git a/llvm/test/Transforms/LICM/non-integral-pointers.ll b/llvm/test/Transforms/LICM/non-integral-pointers.ll
new file mode 100644
index 0000000000000..01336d7d812b3
--- /dev/null
+++ b/llvm/test/Transforms/LICM/non-integral-pointers.ll
@@ -0,0 +1,67 @@
+; RUN: opt -passes=licm -S < %s | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-ni:1"
+
+declare void @use_i64(i64 %0)
+declare void @use_p1(ptr addrspace(1) %0)
+declare i1 @cond()
+
+define void @dont_hoist_ptrtoint(ptr addrspace(1) %p) {
+; CHECK-LABEL: @dont_hoist_ptrtoint
+; CHECK-LABEL: loop
+; CHECK:         ptrtoint
+entry:
+  br label %loop
+
+loop:
+  %p.int = ptrtoint ptr addrspace(1) %p to i64
+  call void @use_i64(i64 %p.int)
+  br label %loop
+}
+
+define void @dont_hoist_inttoptr(i64 %p.int) {
+; CHECK-LABEL: @dont_hoist_inttoptr
+; CHECK-LABEL: loop
+; CHECK:         inttoptr
+entry:
+  br label %loop
+
+loop:
+  %p = inttoptr i64 %p.int to ptr addrspace(1)
+  call void @use_p1(ptr addrspace(1) %p)
+  br label %loop
+}
+
+define i64 @dont_sink_ptrtoint(ptr addrspace(1) %p) {
+; CHECK-LABEL: @dont_sink_ptrtoint
+; CHECK-LABEL: loop
+; CHECK:         ptrtoint
+; CHECK-LABEL: exit
+entry:
+  br label %loop
+
+loop:
+  %p.int = ptrtoint ptr addrspace(1) %p to i64
+  %c = call i1 @cond()
+  br i1 %c, label %loop, label %exit
+
+exit:
+  ret i64 %p.int
+}
+
+define ptr addrspace(1) @dont_sink_inttoptr(i64 %p.int) {
+; CHECK-LABEL: @dont_sink_inttoptr
+; CHECK-LABEL: loop
+; CHECK:         inttoptr
+; CHECK-LABEL: exit
+entry:
+  br label %loop
+
+loop:
+  %p = inttoptr i64 %p.int to ptr addrspace(1)
+  %c = call i1 @cond()
+  br i1 %c, label %loop, label %exit
+
+exit:
+  ret ptr addrspace(1) %p
+}

``````````

</details>


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


More information about the llvm-commits mailing list