[llvm] 6c4d121 - [IR] Do not combine ptrtoaddr and trunc
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 21 06:12:46 PDT 2025
Author: Nikita Popov
Date: 2025-10-21T15:12:36+02:00
New Revision: 6c4d121e7f963d1a53b5fa0aee8832f2b260248b
URL: https://github.com/llvm/llvm-project/commit/6c4d121e7f963d1a53b5fa0aee8832f2b260248b
DIFF: https://github.com/llvm/llvm-project/commit/6c4d121e7f963d1a53b5fa0aee8832f2b260248b.diff
LOG: [IR] Do not combine ptrtoaddr and trunc
The ptrtoaddr result type is required to match the pointer address
width. This means that, unlikely with ptrtoint, it's not legal to
merge a ptrtoint and trunc. This previously resulted in an IR
verifier failure.
Added:
llvm/test/Transforms/InstCombine/ptrtoaddr.ll
Modified:
llvm/lib/IR/Instructions.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index 9060a89bb15ff..3b8fde8aff45f 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -2878,7 +2878,7 @@ unsigned CastInst::isEliminableCastPair(Instruction::CastOps firstOp,
{ 99,99,99, 0, 0,99,99, 0, 0,99,99,99, 4, 0}, // FPTrunc |
{ 99,99,99, 2, 2,99,99, 8, 2,99,99,99, 4, 0}, // FPExt |
{ 1, 0, 0,99,99, 0, 0,99,99,99,99, 7, 3, 0}, // PtrToInt |
- { 1, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // PtrToAddr |
+ { 0, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // PtrToAddr |
{ 99,99,99,99,99,99,99,99,99,11,11,99,15, 0}, // IntToPtr |
{ 5, 5, 5, 0, 0, 5, 5, 0, 0,16,16, 5, 1,14}, // BitCast |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+
diff --git a/llvm/test/Transforms/InstCombine/ptrtoaddr.ll b/llvm/test/Transforms/InstCombine/ptrtoaddr.ll
new file mode 100644
index 0000000000000..410c43c807ed9
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/ptrtoaddr.ll
@@ -0,0 +1,42 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+; The ptrtoaddr folds are also valid for pointers that have external state.
+target datalayout = "pe1:64:64:64:32"
+
+; ptrtoaddr result type is fixed, and can't be combined with integer cast.
+define i32 @ptrtoaddr_trunc(ptr %p) {
+; CHECK-LABEL: define i32 @ptrtoaddr_trunc(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i64
+; CHECK-NEXT: [[TRUNC:%.*]] = trunc i64 [[P_ADDR]] to i32
+; CHECK-NEXT: ret i32 [[TRUNC]]
+;
+ %p.addr = ptrtoaddr ptr %p to i64
+ %trunc = trunc i64 %p.addr to i32
+ ret i32 %trunc
+}
+
+define i128 @ptrtoaddr_zext(ptr %p) {
+; CHECK-LABEL: define i128 @ptrtoaddr_zext(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i64
+; CHECK-NEXT: [[EXT:%.*]] = zext i64 [[P_ADDR]] to i128
+; CHECK-NEXT: ret i128 [[EXT]]
+;
+ %p.addr = ptrtoaddr ptr %p to i64
+ %ext = zext i64 %p.addr to i128
+ ret i128 %ext
+}
+
+define i128 @ptrtoaddr_sext(ptr %p) {
+; CHECK-LABEL: define i128 @ptrtoaddr_sext(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i64
+; CHECK-NEXT: [[EXT:%.*]] = sext i64 [[P_ADDR]] to i128
+; CHECK-NEXT: ret i128 [[EXT]]
+;
+ %p.addr = ptrtoaddr ptr %p to i64
+ %ext = sext i64 %p.addr to i128
+ ret i128 %ext
+}
More information about the llvm-commits
mailing list