From 795925f7b6298fe292362188de5c5b02bba9d426 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes Date: Fri, 3 May 2024 12:17:27 -0700 Subject: [PATCH] [CIR][LowerToLLVM] Fix ptrdiffs in face of !cir.void --- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 24 ++++++++++++------- clang/test/CIR/CodeGen/ptrdiff.c | 18 ++++++++++++++ .../CIR/CodeGen/{ptr_diff.cpp => ptrdiff.cpp} | 0 3 files changed, 34 insertions(+), 8 deletions(-) create mode 100644 clang/test/CIR/CodeGen/ptrdiff.c rename clang/test/CIR/CodeGen/{ptr_diff.cpp => ptrdiff.cpp} (100%) diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 8cbc46e2c010..638d68a776fb 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -2533,6 +2533,9 @@ class CIRPtrDiffOpLowering uint64_t getTypeSize(mlir::Type type, mlir::Operation &op) const { mlir::DataLayout layout(op.getParentOfType()); + // For LLVM purposes we treat void as u8. + if (isa(type)) + type = mlir::cir::IntType::get(type.getContext(), 8, /*isSigned=*/false); return llvm::divideCeil(layout.getTypeSizeInBits(type), 8); } @@ -2552,16 +2555,21 @@ class CIRPtrDiffOpLowering auto ptrTy = op.getLhs().getType().cast(); auto typeSize = getTypeSize(ptrTy.getPointee(), *op); - auto typeSizeVal = rewriter.create( - op.getLoc(), llvmDstTy, mlir::IntegerAttr::get(llvmDstTy, typeSize)); - if (dstTy.isUnsigned()) - rewriter.replaceOpWithNewOp(op, llvmDstTy, diff, - typeSizeVal); - else - rewriter.replaceOpWithNewOp(op, llvmDstTy, diff, - typeSizeVal); + // Avoid silly division by 1. + auto resultVal = diff.getResult(); + if (typeSize != 1) { + auto typeSizeVal = rewriter.create( + op.getLoc(), llvmDstTy, mlir::IntegerAttr::get(llvmDstTy, typeSize)); + if (dstTy.isUnsigned()) + resultVal = rewriter.create(op.getLoc(), llvmDstTy, + diff, typeSizeVal); + else + resultVal = rewriter.create(op.getLoc(), llvmDstTy, + diff, typeSizeVal); + } + rewriter.replaceOp(op, resultVal); return mlir::success(); } }; diff --git a/clang/test/CIR/CodeGen/ptrdiff.c b/clang/test/CIR/CodeGen/ptrdiff.c new file mode 100644 index 000000000000..1a937d5f4272 --- /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; +} \ No newline at end of file diff --git a/clang/test/CIR/CodeGen/ptr_diff.cpp b/clang/test/CIR/CodeGen/ptrdiff.cpp similarity index 100% rename from clang/test/CIR/CodeGen/ptr_diff.cpp rename to clang/test/CIR/CodeGen/ptrdiff.cpp