[clang] [CIR] Upstream pointer subtraction handling (PR #163306)
Shawn K via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 14 13:33:04 PDT 2025
https://github.com/kimsh02 updated https://github.com/llvm/llvm-project/pull/163306
>From 9f2ec3c40d9c4f28531e4a18f392703ca16ab2d7 Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Mon, 13 Oct 2025 13:18:28 -0700
Subject: [PATCH 1/7] Copy incubator tests
---
clang/test/CIR/CodeGen/ptrdiff.c | 18 ++++++++++++++++++
clang/test/CIR/CodeGen/ptrdiff.cpp | 23 +++++++++++++++++++++++
2 files changed, 41 insertions(+)
create mode 100644 clang/test/CIR/CodeGen/ptrdiff.c
create mode 100644 clang/test/CIR/CodeGen/ptrdiff.cpp
diff --git a/clang/test/CIR/CodeGen/ptrdiff.c b/clang/test/CIR/CodeGen/ptrdiff.c
new file mode 100644
index 0000000000000..2ccbbb02dddaa
--- /dev/null
+++ b/clang/test/CIR/CodeGen/ptrdiff.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s
+
+int addrcmp(const void* a, const void* b) {
+ // CIR-LABEL: addrcmp
+ // CIR: %[[R:.*]] = cir.ptr_diff
+ // CIR: cir.cast integral %[[R]] : !s64i -> !s32
+
+ // LLVM-LABEL: addrcmp
+ // LLVM: %[[PTR_A:.*]] = ptrtoint ptr {{.*}} to i64
+ // LLVM: %[[PTR_B:.*]] = ptrtoint ptr {{.*}} to i64
+ // LLVM: %[[SUB:.*]] = sub i64 %[[PTR_A]], %[[PTR_B]]
+ // LLVM-NOT: sdiv
+ // LLVM: trunc i64 %[[SUB]] to i32
+ return *(const void**)a - *(const void**)b;
+}
diff --git a/clang/test/CIR/CodeGen/ptrdiff.cpp b/clang/test/CIR/CodeGen/ptrdiff.cpp
new file mode 100644
index 0000000000000..ba54b7a3b11bf
--- /dev/null
+++ b/clang/test/CIR/CodeGen/ptrdiff.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+typedef unsigned long size_type;
+size_type size(unsigned long *_start, unsigned long *_finish) {
+ return static_cast<size_type>(_finish - _start);
+}
+
+// CHECK: cir.func dso_local @_Z4sizePmS_(%arg0: !cir.ptr<!u64i>
+// CHECK: %3 = cir.load{{.*}} %1 : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
+// CHECK: %4 = cir.load{{.*}} %0 : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
+// CHECK: %5 = cir.ptr_diff %3, %4 : !cir.ptr<!u64i> -> !s64i
+// CHECK: %6 = cir.cast integral %5 : !s64i -> !u64i
+
+long add(char *a, char *b) {
+ return a - b + 1;
+}
+
+// CHECK: cir.func dso_local @_Z3addPcS_(%arg0: !cir.ptr<!s8i>
+// %5 = cir.ptr_diff %3, %4 : !cir.ptr<!s8i> -> !s64i
+// %6 = cir.const #cir.int<1> : !s32i
+// %7 = cir.cast integral %6 : !s32i -> !s64i
+// %8 = cir.binop(add, %5, %7) : !s64i
>From db85047a5f606caad31770219f468f66985b2ed1 Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Mon, 13 Oct 2025 19:05:05 -0700
Subject: [PATCH 2/7] Stash
---
clang/include/clang/CIR/MissingFeatures.h | 2 +-
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 3 +-
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 34 +++++++++++++++++
clang/test/CIR/CodeGen/ptrdiff.c | 14 +++++++
clang/test/CIR/CodeGen/ptrdiff.cpp | 37 +++++++++++++------
5 files changed, 75 insertions(+), 15 deletions(-)
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 4fbae150b587e..8edb4adcf48de 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -321,7 +321,7 @@ struct MissingFeatures {
static bool ifOp() { return false; }
static bool invokeOp() { return false; }
static bool labelOp() { return false; }
- static bool ptrDiffOp() { return false; }
+ static bool ptrDiffOp() { return true; }
static bool ptrStrideOp() { return false; }
static bool switchOp() { return false; }
static bool throwOp() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 637f9ef65c88f..6c6e25c3f6caa 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1735,8 +1735,7 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) {
//
// See more in `EmitSub` in CGExprScalar.cpp.
assert(!cir::MissingFeatures::ptrDiffOp());
- cgf.cgm.errorNYI("ptrdiff");
- return {};
+ return builder.create<cir::PtrDiffOp>(cgf.getLoc(ops.loc), cgf.PtrDiffTy, ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitShl(const BinOpInfo &ops) {
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index f0d73ac872386..5f4fb2aa5c09d 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1499,6 +1499,40 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
return mlir::success();
}
+mlir::LogicalResult CIRToLLVMPtrDiffOpLowering::matchAndRewrite(
+ cir::PtrDiffOp op, OpAdaptor adaptor,
+ mlir::ConversionPatternRewriter &rewriter) const {
+ auto dstTy = mlir::cast<cir::IntType>(op.getType());
+ auto llvmDstTy = getTypeConverter()->convertType(dstTy);
+
+ auto lhs = rewriter.create<mlir::LLVM::PtrToIntOp>(op.getLoc(), llvmDstTy,
+ adaptor.getLhs());
+ auto rhs = rewriter.create<mlir::LLVM::PtrToIntOp>(op.getLoc(), llvmDstTy,
+ adaptor.getRhs());
+
+ auto diff =
+ rewriter.create<mlir::LLVM::SubOp>(op.getLoc(), llvmDstTy, lhs, rhs);
+
+ cir::PointerType ptrTy = op.getLhs().getType();
+ auto typeSize = getTypeSize(ptrTy.getPointee(), *op);
+
+ // Avoid silly division by 1.
+ auto resultVal = diff.getResult();
+ if (typeSize != 1) {
+ auto typeSizeVal = rewriter.create<mlir::LLVM::ConstantOp>(
+ op.getLoc(), llvmDstTy, typeSize);
+
+ if (dstTy.isUnsigned())
+ resultVal =
+ rewriter.create<mlir::LLVM::UDivOp>(op.getLoc(), diff, typeSizeVal);
+ else
+ resultVal =
+ rewriter.create<mlir::LLVM::SDivOp>(op.getLoc(), diff, typeSizeVal);
+ }
+ rewriter.replaceOp(op, resultVal);
+ return mlir::success();
+}
+
mlir::LogicalResult CIRToLLVMExpectOpLowering::matchAndRewrite(
cir::ExpectOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
diff --git a/clang/test/CIR/CodeGen/ptrdiff.c b/clang/test/CIR/CodeGen/ptrdiff.c
index 2ccbbb02dddaa..ef37d4b139568 100644
--- a/clang/test/CIR/CodeGen/ptrdiff.c
+++ b/clang/test/CIR/CodeGen/ptrdiff.c
@@ -16,3 +16,17 @@ int addrcmp(const void* a, const void* b) {
// LLVM: trunc i64 %[[SUB]] to i32
return *(const void**)a - *(const void**)b;
}
+
+unsigned long long test_ptr_diff(int *a, int* b) {
+ // CIR-LABEL: test_ptr_diff
+ // CIR: %[[D:.*]] = cir.ptr_diff{{.*}} : !cir.ptr<!s32i> -> !u64i
+ // CIR: cir.return %[[D]] : !u64i
+
+ // LLVM-LABEL: @_Z13test_ptr_diffPiS_
+ // LLVM: %[[IA:.*]] = ptrtoint ptr %{{.*}} to i64
+ // LLVM: %[[IB:.*]] = ptrtoint ptr %{{.*}} to i64
+ // LLVM: %[[SUB:.*]] = sub i64 %[[IA]], %[[IB]]
+ // LLVM: %[[Q:.*]] = sdiv exact i64 %[[SUB]], 4
+ // LLVM: ret i64 %[[Q]]
+ return a - b;
+}
diff --git a/clang/test/CIR/CodeGen/ptrdiff.cpp b/clang/test/CIR/CodeGen/ptrdiff.cpp
index ba54b7a3b11bf..32a3955807b8f 100644
--- a/clang/test/CIR/CodeGen/ptrdiff.cpp
+++ b/clang/test/CIR/CodeGen/ptrdiff.cpp
@@ -2,22 +2,35 @@
// RUN: FileCheck --input-file=%t.cir %s
typedef unsigned long size_type;
+
size_type size(unsigned long *_start, unsigned long *_finish) {
+ // CIR-LABEL: cir.func dso_local @_Z4sizePmS_
+ // CIR: %[[D:.*]] = cir.ptr_diff {{.*}} : !cir.ptr<!u64i> -> !s64i
+ // CIR: %[[U:.*]] = cir.cast integral %[[D]] : !s64i -> !u64i
+ // CIR: cir.return %[[U]] : !u64i
+
+ // LLVM-LABEL: @_Z4sizePmS_
+ // LLVM: ptrtoint ptr {{.*}} to i64
+ // LLVM: ptrtoint ptr {{.*}} to i64
+ // LLVM: %[[SUB:.*]] = sub i64 {{.*}}, {{.*}}
+ // LLVM: %[[DIV:.*]] = sdiv exact i64 %[[SUB]], 8
+ // LLVM: ret i64 %[[DIV]]
return static_cast<size_type>(_finish - _start);
}
-// CHECK: cir.func dso_local @_Z4sizePmS_(%arg0: !cir.ptr<!u64i>
-// CHECK: %3 = cir.load{{.*}} %1 : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
-// CHECK: %4 = cir.load{{.*}} %0 : !cir.ptr<!cir.ptr<!u64i>>, !cir.ptr<!u64i>
-// CHECK: %5 = cir.ptr_diff %3, %4 : !cir.ptr<!u64i> -> !s64i
-// CHECK: %6 = cir.cast integral %5 : !s64i -> !u64i
-
long add(char *a, char *b) {
+ // CIR-LABEL: cir.func dso_local @_Z3addPcS_
+ // CIR: %[[D:.*]] = cir.ptr_diff {{.*}} : !cir.ptr<!s8i> -> !s64i
+ // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
+ // CIR: %[[C1W:.*]] = cir.cast integral %[[C1]] : !s32i -> !s64i
+ // CIR: %[[S:.*]] = cir.binop(add, %[[D]], %[[C1W]]) : !s64i
+ // CIR: cir.return %[[S]] : !s64i
+
+ // LLVM-LABEL: @_Z3addPcS_
+ // LLVM: ptrtoint ptr {{.*}} to i64
+ // LLVM: ptrtoint ptr {{.*}} to i64
+ // LLVM: %[[SUB:.*]] = sub i64 {{.*}}, {{.*}}
+ // LLVM: %[[ADD1:.*]] = add i64 %[[SUB]], 1
+ // LLVM: ret i64 %[[ADD1]]
return a - b + 1;
}
-
-// CHECK: cir.func dso_local @_Z3addPcS_(%arg0: !cir.ptr<!s8i>
-// %5 = cir.ptr_diff %3, %4 : !cir.ptr<!s8i> -> !s64i
-// %6 = cir.const #cir.int<1> : !s32i
-// %7 = cir.cast integral %6 : !s32i -> !s64i
-// %8 = cir.binop(add, %5, %7) : !s64i
>From a3709f9303d2db3f07b878501bda4ba4f93722ae Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Mon, 13 Oct 2025 19:06:12 -0700
Subject: [PATCH 3/7] Clang-format
---
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 6c6e25c3f6caa..ff77c0ef5a540 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1735,7 +1735,8 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) {
//
// See more in `EmitSub` in CGExprScalar.cpp.
assert(!cir::MissingFeatures::ptrDiffOp());
- return builder.create<cir::PtrDiffOp>(cgf.getLoc(ops.loc), cgf.PtrDiffTy, ops.lhs, ops.rhs);
+ return builder.create<cir::PtrDiffOp>(cgf.getLoc(ops.loc), cgf.PtrDiffTy,
+ ops.lhs, ops.rhs);
}
mlir::Value ScalarExprEmitter::emitShl(const BinOpInfo &ops) {
>From 0ff02185f99e2047f5a73cf691876b6f48a188a5 Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Tue, 14 Oct 2025 12:33:37 -0700
Subject: [PATCH 4/7] Stash
---
clang/include/clang/CIR/Dialect/IR/CIROps.td | 31 +++++++++++++++++++
clang/include/clang/CIR/MissingFeatures.h | 3 +-
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 2 +-
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 9 ++++++
4 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 4c15d9ed0f834..56ff289f91a93 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -4044,6 +4044,37 @@ def CIR_ExpectOp : CIR_Op<"expect", [
}];
}
+//===----------------------------------------------------------------------===//
+// PtrDiffOp
+//===----------------------------------------------------------------------===//
+
+def CIR_PtrDiffOp : CIR_Op<"ptr_diff", [Pure, SameTypeOperands]> {
+ let summary = "Pointer subtraction arithmetic";
+ let description = [{
+ The cir.ptr_diff operation computes the difference between two pointers that
+ have the same element type
+
+ The result reflects the ABI-defined size of the pointed-to type. For example,
+ subtracting two !cir.ptr<!u64i> values may yield 1, representing an 8-byte
+ difference. In contrast, for pointers to void or function types, a result of
+ 8 corresponds to an 8-byte difference.
+
+ Example:
+
+ ```mlir
+ %7 = cir.ptr_diff %0, %1 : !cir.ptr<!u64i> -> !u64i
+ ```
+ }];
+
+ let arguments = (ins CIR_PointerType:$lhs, CIR_PointerType:$rhs);
+ let results = (outs CIR_AnyFundamentalIntType:$result);
+
+ let assemblyFormat = [{
+ $lhs `,` $rhs `:` qualified(type($lhs)) `->` qualified(type($result))
+ attr-dict
+ }];
+}
+
//===----------------------------------------------------------------------===//
// Floating Point Ops
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 8edb4adcf48de..d133453c137fb 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -321,7 +321,8 @@ struct MissingFeatures {
static bool ifOp() { return false; }
static bool invokeOp() { return false; }
static bool labelOp() { return false; }
- static bool ptrDiffOp() { return true; }
+ static bool ptrDiffOp() { return false; }
+ static bool llvmLoweringPtrDiffConsidersPointee() {return false; }
static bool ptrStrideOp() { return false; }
static bool switchOp() { return false; }
static bool throwOp() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index ff77c0ef5a540..8889bbeebe399 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -1734,7 +1734,7 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) {
// LLVM we shall take VLA's, division by element size, etc.
//
// See more in `EmitSub` in CGExprScalar.cpp.
- assert(!cir::MissingFeatures::ptrDiffOp());
+ assert(!cir::MissingFeatures::llvmLoweringPtrDiffConsidersPointee());
return builder.create<cir::PtrDiffOp>(cgf.getLoc(ops.loc), cgf.PtrDiffTy,
ops.lhs, ops.rhs);
}
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 5f4fb2aa5c09d..19d734df42331 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1499,6 +1499,15 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
return mlir::success();
}
+uint64_t CIRToLLVMPtrDiffOpLowering::getTypeSize(mlir::Type type,
+ mlir::Operation &op) const {
+ mlir::DataLayout layout(op.getParentOfType<mlir::ModuleOp>());
+ // For LLVM purposes we treat void as u8.
+ if (isa<cir::VoidType>(type))
+ type = cir::IntType::get(type.getContext(), 8, /*isSigned=*/false);
+ return llvm::divideCeil(layout.getTypeSizeInBits(type), 8);
+}
+
mlir::LogicalResult CIRToLLVMPtrDiffOpLowering::matchAndRewrite(
cir::PtrDiffOp op, OpAdaptor adaptor,
mlir::ConversionPatternRewriter &rewriter) const {
>From 61bc2569fc4792ddd97d81ddace687b1e10ca451 Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Tue, 14 Oct 2025 13:30:34 -0700
Subject: [PATCH 5/7] Fix testcases
---
.../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 4 +--
clang/test/CIR/CodeGen/ptrdiff.c | 17 +++++++-----
clang/test/CIR/CodeGen/ptrdiff.cpp | 27 ++-----------------
3 files changed, 14 insertions(+), 34 deletions(-)
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 19d734df42331..4b8d912409a8e 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1499,8 +1499,8 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
return mlir::success();
}
-uint64_t CIRToLLVMPtrDiffOpLowering::getTypeSize(mlir::Type type,
- mlir::Operation &op) const {
+static uint64_t getTypeSize(mlir::Type type,
+ mlir::Operation &op) {
mlir::DataLayout layout(op.getParentOfType<mlir::ModuleOp>());
// For LLVM purposes we treat void as u8.
if (isa<cir::VoidType>(type))
diff --git a/clang/test/CIR/CodeGen/ptrdiff.c b/clang/test/CIR/CodeGen/ptrdiff.c
index ef37d4b139568..33a0c3ad4faf4 100644
--- a/clang/test/CIR/CodeGen/ptrdiff.c
+++ b/clang/test/CIR/CodeGen/ptrdiff.c
@@ -6,9 +6,9 @@
int addrcmp(const void* a, const void* b) {
// CIR-LABEL: addrcmp
// CIR: %[[R:.*]] = cir.ptr_diff
- // CIR: cir.cast integral %[[R]] : !s64i -> !s32
+ // CIR: cir.cast integral %[[R]] : !s64i -> !s32i
- // LLVM-LABEL: addrcmp
+ // LLVM-LABEL: define dso_local i32 @addrcmp(
// LLVM: %[[PTR_A:.*]] = ptrtoint ptr {{.*}} to i64
// LLVM: %[[PTR_B:.*]] = ptrtoint ptr {{.*}} to i64
// LLVM: %[[SUB:.*]] = sub i64 %[[PTR_A]], %[[PTR_B]]
@@ -19,14 +19,17 @@ int addrcmp(const void* a, const void* b) {
unsigned long long test_ptr_diff(int *a, int* b) {
// CIR-LABEL: test_ptr_diff
- // CIR: %[[D:.*]] = cir.ptr_diff{{.*}} : !cir.ptr<!s32i> -> !u64i
- // CIR: cir.return %[[D]] : !u64i
+ // CIR: %[[D:.*]] = cir.ptr_diff {{.*}} : !cir.ptr<!s32i> -> !s64i
+ // CIR: %[[U:.*]] = cir.cast integral %[[D]] : !s64i -> !u64i
+ // CIR: cir.return {{.*}} : !u64i
- // LLVM-LABEL: @_Z13test_ptr_diffPiS_
+ // LLVM-LABEL: define dso_local i64 @test_ptr_diff(
// LLVM: %[[IA:.*]] = ptrtoint ptr %{{.*}} to i64
// LLVM: %[[IB:.*]] = ptrtoint ptr %{{.*}} to i64
// LLVM: %[[SUB:.*]] = sub i64 %[[IA]], %[[IB]]
- // LLVM: %[[Q:.*]] = sdiv exact i64 %[[SUB]], 4
- // LLVM: ret i64 %[[Q]]
+ // LLVM: %[[Q:.*]] = sdiv{{( exact)?}} i64 %[[SUB]], 4
+ // LLVM: store i64 %[[Q]], ptr %[[RETADDR:.*]], align
+ // LLVM: %[[RETLOAD:.*]] = load i64, ptr %[[RETADDR]], align
+ // LLVM: ret i64 %[[RETLOAD]]
return a - b;
}
diff --git a/clang/test/CIR/CodeGen/ptrdiff.cpp b/clang/test/CIR/CodeGen/ptrdiff.cpp
index 32a3955807b8f..2c0aed6089816 100644
--- a/clang/test/CIR/CodeGen/ptrdiff.cpp
+++ b/clang/test/CIR/CodeGen/ptrdiff.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
-// RUN: FileCheck --input-file=%t.cir %s
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
typedef unsigned long size_type;
@@ -7,30 +7,7 @@ size_type size(unsigned long *_start, unsigned long *_finish) {
// CIR-LABEL: cir.func dso_local @_Z4sizePmS_
// CIR: %[[D:.*]] = cir.ptr_diff {{.*}} : !cir.ptr<!u64i> -> !s64i
// CIR: %[[U:.*]] = cir.cast integral %[[D]] : !s64i -> !u64i
- // CIR: cir.return %[[U]] : !u64i
+ // CIR: cir.return {{.*}} : !u64i
- // LLVM-LABEL: @_Z4sizePmS_
- // LLVM: ptrtoint ptr {{.*}} to i64
- // LLVM: ptrtoint ptr {{.*}} to i64
- // LLVM: %[[SUB:.*]] = sub i64 {{.*}}, {{.*}}
- // LLVM: %[[DIV:.*]] = sdiv exact i64 %[[SUB]], 8
- // LLVM: ret i64 %[[DIV]]
return static_cast<size_type>(_finish - _start);
}
-
-long add(char *a, char *b) {
- // CIR-LABEL: cir.func dso_local @_Z3addPcS_
- // CIR: %[[D:.*]] = cir.ptr_diff {{.*}} : !cir.ptr<!s8i> -> !s64i
- // CIR: %[[C1:.*]] = cir.const #cir.int<1> : !s32i
- // CIR: %[[C1W:.*]] = cir.cast integral %[[C1]] : !s32i -> !s64i
- // CIR: %[[S:.*]] = cir.binop(add, %[[D]], %[[C1W]]) : !s64i
- // CIR: cir.return %[[S]] : !s64i
-
- // LLVM-LABEL: @_Z3addPcS_
- // LLVM: ptrtoint ptr {{.*}} to i64
- // LLVM: ptrtoint ptr {{.*}} to i64
- // LLVM: %[[SUB:.*]] = sub i64 {{.*}}, {{.*}}
- // LLVM: %[[ADD1:.*]] = add i64 %[[SUB]], 1
- // LLVM: ret i64 %[[ADD1]]
- return a - b + 1;
-}
>From 50412c36ad1c771b221d6db91fe320df5a9e5c2d Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Tue, 14 Oct 2025 13:31:43 -0700
Subject: [PATCH 6/7] Clang-format
---
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 4b8d912409a8e..70c152f8722b0 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1499,8 +1499,7 @@ mlir::LogicalResult CIRToLLVMConstantOpLowering::matchAndRewrite(
return mlir::success();
}
-static uint64_t getTypeSize(mlir::Type type,
- mlir::Operation &op) {
+static uint64_t getTypeSize(mlir::Type type, mlir::Operation &op) {
mlir::DataLayout layout(op.getParentOfType<mlir::ModuleOp>());
// For LLVM purposes we treat void as u8.
if (isa<cir::VoidType>(type))
>From 52f0f44f5e58277335a74a6a80c20944ad824ffc Mon Sep 17 00:00:00 2001
From: kimsh02 <kimshawn02 at icloud.com>
Date: Tue, 14 Oct 2025 13:32:52 -0700
Subject: [PATCH 7/7] Clang-format
---
clang/include/clang/CIR/MissingFeatures.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index d133453c137fb..de3bc9487bc8c 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -322,7 +322,7 @@ struct MissingFeatures {
static bool invokeOp() { return false; }
static bool labelOp() { return false; }
static bool ptrDiffOp() { return false; }
- static bool llvmLoweringPtrDiffConsidersPointee() {return false; }
+ static bool llvmLoweringPtrDiffConsidersPointee() { return false; }
static bool ptrStrideOp() { return false; }
static bool switchOp() { return false; }
static bool throwOp() { return false; }
More information about the cfe-commits
mailing list