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

Csanád Hajdú via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 12 01:43:32 PDT 2024


https://github.com/Il-Capitano updated https://github.com/llvm/llvm-project/pull/97272

>From 0a9ae5c3a5e8ce240d1474d14c2b9208782148c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Thu, 20 Jun 2024 11:45:06 +0200
Subject: [PATCH 1/2] [LICM] Prevent LICM of ptrtoint and inttoptr when using
 non-integral pointers

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.
---
 llvm/lib/Transforms/Scalar/LICM.cpp           | 15 +++++
 .../Transforms/LICM/non-integral-pointers.ll  | 67 +++++++++++++++++++
 2 files changed, 82 insertions(+)
 create mode 100644 llvm/test/Transforms/LICM/non-integral-pointers.ll

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
+}

>From ffa6cd4efdd7a5286dacaf79afeb89eb359c7dd3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Csan=C3=A1d=20Hajd=C3=BA?= <csanad.hajdu at arm.com>
Date: Fri, 12 Jul 2024 10:39:37 +0200
Subject: [PATCH 2/2] Rerun clang-format

---
 llvm/lib/Transforms/Scalar/LICM.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index f286d910f932e..f360379e9df04 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -65,9 +65,9 @@
 #include "llvm/IR/DebugInfoMetadata.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/Dominators.h"
+#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"



More information about the llvm-commits mailing list