diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 169ece0991ad..a1c2f73794af 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -485,10 +485,12 @@ class CIRPtrStrideOpLowering auto *tc = getTypeConverter(); const auto resultTy = tc->convertType(ptrStrideOp.getType()); auto elementTy = tc->convertType(ptrStrideOp.getElementTy()); - auto ctx = elementTy.getContext(); + auto *ctx = elementTy.getContext(); - // void doesn't really have a layout to use in GEPs, make it i8 instead. - if (elementTy.isa()) + // void and function types doesn't really have a layout to use in GEPs, + // make it i8 instead. + if (elementTy.isa() || + elementTy.isa()) elementTy = mlir::IntegerType::get(elementTy.getContext(), 8, mlir::IntegerType::Signless); diff --git a/clang/test/CIR/CodeGen/pointer-arith-ext.c b/clang/test/CIR/CodeGen/pointer-arith-ext.c index 5db612254d6e..f64915b0569c 100644 --- a/clang/test/CIR/CodeGen/pointer-arith-ext.c +++ b/clang/test/CIR/CodeGen/pointer-arith-ext.c @@ -48,13 +48,41 @@ void *f4(void *a, int b) { return a - b; } // Similar to f4, just make sure it does not crash. void *f4_1(void *a, int b) { return (a -= b); } +FP f5(FP a, int b) { return a + b; } +// CIR-LABEL: f5 +// CIR: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr>>, !cir.ptr> +// CIR: %[[STRIDE:.*]] = cir.load {{.*}} : !cir.ptr, !s32i +// CIR: cir.ptr_stride(%[[PTR]] : !cir.ptr>, %[[STRIDE]] : !s32i) + +// LLVM-LABEL: f5 +// LLVM: %[[PTR:.*]] = load ptr, ptr {{.*}}, align 8 +// LLVM: %[[TOEXT:.*]] = load i32, ptr {{.*}}, align 4 +// LLVM: %[[STRIDE:.*]] = sext i32 %[[TOEXT]] to i64 +// LLVM: getelementptr i8, ptr %[[PTR]], i64 %[[STRIDE]] + +// These test the same paths above, just make sure it does not crash. +FP f5_1(FP a, int b) { return (a += b); } +FP f6(int a, FP b) { return a + b; } +FP f6_1(int a, FP b) { return (a += b); } + +FP f7(FP a, int b) { return a - b; } +// CIR-LABEL: f7 +// CIR: %[[PTR:.*]] = cir.load {{.*}} : !cir.ptr>>, !cir.ptr> +// CIR: %[[STRIDE:.*]] = cir.load {{.*}} : !cir.ptr, !s32i +// CIR: %[[SUB:.*]] = cir.unary(minus, %[[STRIDE]]) : !s32i, !s32i +// CIR: cir.ptr_stride(%[[PTR]] : !cir.ptr>, %[[SUB]] : !s32i) + +// LLVM-LABEL: f7 +// LLVM: %[[PTR:.*]] = load ptr, ptr {{.*}}, align 8 +// LLVM: %[[TOEXT:.*]] = load i32, ptr {{.*}}, align 4 +// LLVM: %[[STRIDE:.*]] = sext i32 %[[TOEXT]] to i64 +// LLVM: %[[SUB:.*]] = sub i64 0, %[[STRIDE]] +// LLVM: getelementptr i8, ptr %[[PTR]], i64 %[[SUB]] + +// Similar to f7, just make sure it does not crash. +FP f7_1(FP a, int b) { return (a -= b); } + // FIXME: add support for the remaining ones. -// FP f5(FP a, int b) { return a + b; } -// FP f5_1(FP a, int b) { return (a += b); } -// FP f6(int a, FP b) { return a + b; } -// FP f6_1(int a, FP b) { return (a += b); } -// FP f7(FP a, int b) { return a - b; } -// FP f7_1(FP a, int b) { return (a -= b); } // void f8(void *a, int b) { return *(a + b); } // void f8_1(void *a, int b) { return a[b]; } @@ -69,4 +97,4 @@ unsigned char *p(unsigned int x) { // CIR: cir.ptr_stride({{.*}} : !cir.ptr, %[[SUB]] : !u32i), !cir.ptr // LLVM-LABEL: @p -// LLVM: getelementptr i8, ptr {{.*}} \ No newline at end of file +// LLVM: getelementptr i8, ptr {{.*}}