[clang] [CIR] Upstream pointer arithmetic support (PR #138041)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 30 15:54:34 PDT 2025
================
@@ -1152,8 +1169,72 @@ getUnwidenedIntegerType(const ASTContext &astContext, const Expr *e) {
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf,
const BinOpInfo &op,
bool isSubtraction) {
- cgf.cgm.errorNYI(op.loc, "pointer arithmetic");
- return {};
+ // Must have binary (not unary) expr here. Unary pointer
+ // increment/decrement doesn't use this path.
+ const BinaryOperator *expr = cast<BinaryOperator>(op.e);
+
+ mlir::Value pointer = op.lhs;
+ Expr *pointerOperand = expr->getLHS();
+ mlir::Value index = op.rhs;
+ Expr *indexOperand = expr->getRHS();
+
+ // In a subtraction, the LHS is always the pointer.
+ if (!isSubtraction && !mlir::isa<cir::PointerType>(pointer.getType())) {
+ std::swap(pointer, index);
+ std::swap(pointerOperand, indexOperand);
+ }
+
+ // Some versions of glibc and gcc use idioms (particularly in their malloc
+ // routines) that add a pointer-sized integer (known to be a pointer value)
+ // to a null pointer in order to cast the value back to an integer or as
+ // part of a pointer alignment algorithm. This is undefined behavior, but
+ // we'd like to be able to compile programs that use it.
+ //
+ // Normally, we'd generate a GEP with a null-pointer base here in response
+ // to that code, but it's also UB to dereference a pointer created that
+ // way. Instead (as an acknowledged hack to tolerate the idiom) we will
+ // generate a direct cast of the integer value to a pointer.
+ //
+ // The idiom (p = nullptr + N) is not met if any of the following are true:
+ //
+ // The operation is subtraction.
+ // The index is not pointer-sized.
+ // The pointer type is not byte-sized.
+ //
+ if (BinaryOperator::isNullPointerArithmeticExtension(
+ cgf.getContext(), op.opcode, expr->getLHS(), expr->getRHS()))
+ return cgf.getBuilder().createIntToPtr(index, pointer.getType());
+
+ // Differently from LLVM codegen, ABI bits for index sizes is handled during
+ // LLVM lowering.
+
+ // If this is subtraction, negate the index.
+ if (isSubtraction)
+ index = cgf.getBuilder().createNeg(index);
----------------
erichkeane wrote:
Does this work with pointers?
https://github.com/llvm/llvm-project/pull/138041
More information about the cfe-commits
mailing list