Author: Erich Keane
Date: 2026-04-07T14:27:04-07:00
New Revision: a50839de8aab4a42a70d3c8105ecf80ef98f74a2

URL: 
https://github.com/llvm/llvm-project/commit/a50839de8aab4a42a70d3c8105ecf80ef98f74a2
DIFF: 
https://github.com/llvm/llvm-project/commit/a50839de8aab4a42a70d3c8105ecf80ef98f74a2.diff

LOG: [CIR] Add lowering for long-double increment/decrement (#190812)

This showed up a handful of times in some benchmarks. Supporting
long-double is pretty trivial, so this patch does so, with some work to
make sure all 3 formats of long-double work in the test (plus some
    command-line replacement, hopefully that isn't too confusing).

The NYI is left in place, as we're not yet implementing any of the
'half' types (or other smaller FP types).

Added: 
    clang/test/CIR/CodeGen/long-double-inc-dec.cpp

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 9dec721269267..b1498f376725d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -694,7 +694,8 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
         return {};
       }
 
-      if (mlir::isa<cir::SingleType, cir::DoubleType>(value.getType())) {
+      if (mlir::isa<cir::SingleType, cir::DoubleType, cir::LongDoubleType>(
+              value.getType())) {
         // Create the inc/dec operation.
         // NOTE(CIR): clang calls CreateAdd but folds this to a unary op
         value = emitIncOrDec(e, value);

diff  --git a/clang/test/CIR/CodeGen/long-double-inc-dec.cpp 
b/clang/test/CIR/CodeGen/long-double-inc-dec.cpp
new file mode 100644
index 0000000000000..9665e090f5dca
--- /dev/null
+++ b/clang/test/CIR/CodeGen/long-double-inc-dec.cpp
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-64 -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR -DLDTY=cir.double
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-64 -fclangir 
-emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM,LLVMCIR 
-DLDTY=double -DONE=1 -DNEGONE=-1
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-64 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM,OGCG -DLDTY=double 
-DONE=1 -DNEGONE=-1
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-80 -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR -DLDTY=cir.f80
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-80 -fclangir 
-emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM,LLVMCIR 
-DLDTY=x86_fp80 -DONE=0xK3FFF8 -DNEGONE=0xKBFFF8
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-80 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM,OGCG 
-DLDTY=x86_fp80 -DONE=0xK3FFF8 -DNEGONE=0xKBFFF8
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-128 
-fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR -DLDTY=cir.f128
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-128 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM,LLVMCIR 
-DLDTY=fp128 -DONE=0xL00000000000000003FFF -DNEGONE=0xL0000000000000000BFFF
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -mlong-double-128 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM,OGCG -DLDTY=fp128 
-DONE=0xL00000000000000003FFF -DNEGONE=0xL0000000000000000BFFF
+
+extern "C" long double do_pre_inc(long double d) {
+  // CIR-LABEL: @do_pre_inc(
+  // CIR: %[[ARG_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>, ["d", init]
+  // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>
+  //
+  // LLVM-LABEL: @do_pre_inc(
+  // LLVM: %[[ARG_ALLOCA:.*]] = alloca [[LDTY]]
+  // LLVMCIR: %[[RET_ALLOCA:.*]] = alloca [[LDTY]]
+
+  return ++d;
+  // CIR: %[[ARG_LOAD:.*]]  = cir.load {{.*}}%[[ARG_ALLOCA]] : 
!cir.ptr<!cir.long_double<![[LDTY]]>>, !cir.long_double<![[LDTY]]>
+  // CIR: %[[ARG_INC:.*]] = cir.inc %[[ARG_LOAD]]
+  // CIR: cir.store{{.*}} %[[ARG_INC]], %[[ARG_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: cir.store %[[ARG_INC]], %[[RET_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: %[[LOAD_RET:.*]] = cir.load %[[RET_ALLOCA]]
+  // CIR: cir.return %[[LOAD_RET]] : !cir.long_double<![[LDTY]]>
+  //
+  // LLVM: %[[ARG_LOAD:.*]] = load [[LDTY]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: %[[ARG_INC:.*]] = fadd [[LDTY]] [[ONE]]{{.*}}, %[[ARG_LOAD]]
+  // OGCG: %[[ARG_INC:.*]] = fadd [[LDTY]] %[[ARG_LOAD]], [[ONE]]{{.*}}
+  // LLVM: store [[LDTY]] %[[ARG_INC]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: store [[LDTY]] %[[ARG_INC]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: %[[LOAD_RET:.*]] = load [[LDTY]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: ret [[LDTY]] %[[LOAD_RET]]
+  // OGCG: ret [[LDTY]] %[[ARG_INC]]
+}
+extern "C" long double do_post_inc(long double d) {
+  // CIR-LABEL: @do_post_inc(
+  // CIR: %[[ARG_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>, ["d", init]
+  // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>
+  //
+  // LLVM-LABEL: @do_post_inc(
+  // LLVM: %[[ARG_ALLOCA:.*]] = alloca [[LDTY]]
+  // LLVMCIR: %[[RET_ALLOCA:.*]] = alloca [[LDTY]]
+
+  return d++;
+  // CIR: %[[ARG_LOAD:.*]]  = cir.load {{.*}}%[[ARG_ALLOCA]] : 
!cir.ptr<!cir.long_double<![[LDTY]]>>, !cir.long_double<![[LDTY]]>
+  // CIR: %[[ARG_INC:.*]] = cir.inc %[[ARG_LOAD]]
+  // CIR: cir.store{{.*}} %[[ARG_INC]], %[[ARG_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: cir.store %[[ARG_LOAD]], %[[RET_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: %[[LOAD_RET:.*]] = cir.load %[[RET_ALLOCA]]
+  // CIR: cir.return %[[LOAD_RET]] : !cir.long_double<![[LDTY]]>
+  //
+  // LLVM: %[[ARG_LOAD:.*]] = load [[LDTY]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: %[[ARG_INC:.*]] = fadd [[LDTY]] [[ONE]]{{.*}}, %[[ARG_LOAD]]
+  // OGCG: %[[ARG_INC:.*]] = fadd [[LDTY]] %[[ARG_LOAD]], [[ONE]]{{.*}}
+  // LLVM: store [[LDTY]] %[[ARG_INC]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: store [[LDTY]] %[[ARG_LOAD]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: %[[LOAD_RET:.*]] = load [[LDTY]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: ret [[LDTY]] %[[LOAD_RET]]
+  // OGCG: ret [[LDTY]] %[[ARG_LOAD]]
+}
+
+extern "C" long double do_pre_dec(long double d) {
+  // CIR-LABEL: @do_pre_dec(
+  // CIR: %[[ARG_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>, ["d", init]
+  // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>
+  //
+  // LLVM-LABEL: @do_pre_dec(
+  // LLVM: %[[ARG_ALLOCA:.*]] = alloca [[LDTY]]
+  // LLVMCIR: %[[RET_ALLOCA:.*]] = alloca [[LDTY]]
+
+  return --d;
+  // CIR: %[[ARG_LOAD:.*]]  = cir.load {{.*}}%[[ARG_ALLOCA]] : 
!cir.ptr<!cir.long_double<![[LDTY]]>>, !cir.long_double<![[LDTY]]>
+  // CIR: %[[ARG_DEC:.*]] = cir.dec %[[ARG_LOAD]]
+  // CIR: cir.store{{.*}} %[[ARG_DEC]], %[[ARG_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: cir.store %[[ARG_DEC]], %[[RET_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: %[[LOAD_RET:.*]] = cir.load %[[RET_ALLOCA]]
+  // CIR: cir.return %[[LOAD_RET]] : !cir.long_double<![[LDTY]]>
+  //
+  // LLVM: %[[ARG_LOAD:.*]] = load [[LDTY]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: %[[ARG_DEC:.*]] = fadd [[LDTY]] [[NEGONE]]{{.*}}, %[[ARG_LOAD]]
+  // OGCG: %[[ARG_DEC:.*]] = fadd [[LDTY]] %[[ARG_LOAD]], [[NEGONE]]{{.*}}
+  // LLVM: store [[LDTY]] %[[ARG_DEC]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: store [[LDTY]] %[[ARG_DEC]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: %[[LOAD_RET:.*]] = load [[LDTY]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: ret [[LDTY]] %[[LOAD_RET]]
+  // OGCG: ret [[LDTY]] %[[ARG_DEC]]
+}
+extern "C" long double do_post_dec(long double d) {
+  // CIR-LABEL: @do_post_dec(
+  // CIR: %[[ARG_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>, ["d", init]
+  // CIR: %[[RET_ALLOCA:.*]] = cir.alloca !cir.long_double<![[LDTY]]>, 
!cir.ptr<!cir.long_double<![[LDTY]]>>
+  //
+  // LLVM-LABEL: @do_post_dec(
+  // LLVM: %[[ARG_ALLOCA:.*]] = alloca [[LDTY]]
+  // LLVMCIR: %[[RET_ALLOCA:.*]] = alloca [[LDTY]]
+
+  return d--;
+  // CIR: %[[ARG_LOAD:.*]]  = cir.load {{.*}}%[[ARG_ALLOCA]] : 
!cir.ptr<!cir.long_double<![[LDTY]]>>, !cir.long_double<![[LDTY]]>
+  // CIR: %[[ARG_DEC:.*]] = cir.dec %[[ARG_LOAD]]
+  // CIR: cir.store{{.*}} %[[ARG_DEC]], %[[ARG_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: cir.store %[[ARG_LOAD]], %[[RET_ALLOCA]] : 
!cir.long_double<![[LDTY]]>, !cir.ptr<!cir.long_double<![[LDTY]]>>
+  // CIR: %[[LOAD_RET:.*]] = cir.load %[[RET_ALLOCA]]
+  // CIR: cir.return %[[LOAD_RET]] : !cir.long_double<![[LDTY]]>
+  //
+  // LLVM: %[[ARG_LOAD:.*]] = load [[LDTY]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: %[[ARG_DEC:.*]] = fadd [[LDTY]] [[NEGONE]]{{.*}}, %[[ARG_LOAD]]
+  // OGCG: %[[ARG_DEC:.*]] = fadd [[LDTY]] %[[ARG_LOAD]], [[NEGONE]]{{.*}}
+  // LLVM: store [[LDTY]] %[[ARG_DEC]], ptr %[[ARG_ALLOCA]]
+  // LLVMCIR: store [[LDTY]] %[[ARG_LOAD]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: %[[LOAD_RET:.*]] = load [[LDTY]], ptr %[[RET_ALLOCA]]
+  // LLVMCIR: ret [[LDTY]] %[[LOAD_RET]]
+  // OGCG: ret [[LDTY]] %[[ARG_LOAD]]
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to