https://github.com/AmrDeveloper created 
https://github.com/llvm/llvm-project/pull/224851

Add support for experimental strict floating-point for Complex Add & Sub ops

>From a5ec0eb6f809f018e4cb424a92857a16c2fc0de6 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Sat, 19 Sep 2026 19:43:04 +0200
Subject: [PATCH] [CIR] Support strict floating-point in Complex Add & Sub

---
 .../CIR/Dialect/Builder/CIRBaseBuilder.h      |  18 ++++
 clang/include/clang/CIR/Dialect/IR/CIROps.td  |  13 ++-
 clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp   |   4 +-
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  70 +++++++++---
 clang/test/CIR/CodeGen/complex-strict-fp.cpp  | 100 ++++++++++++++++++
 5 files changed, 187 insertions(+), 18 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/complex-strict-fp.cpp

diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h 
b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index 3a52960000a14..66b199e8b5ca7 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -326,6 +326,24 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
     return cir::ComplexImagOp::create(*this, loc, resultType, operand);
   }
 
+  mlir::Value createComplexAdd(mlir::Location loc, mlir::Value lhs,
+                               mlir::Value rhs) {
+    cir::FenvAttr fenv;
+    if (isAnyFloatingPointType(
+            mlir::cast<cir::ComplexType>(lhs.getType()).getElementType()))
+      fenv = getConstrainedFPAttr();
+    return cir::ComplexAddOp::create(*this, loc, lhs, rhs, fenv);
+  }
+
+  mlir::Value createComplexSub(mlir::Location loc, mlir::Value lhs,
+                               mlir::Value rhs) {
+    cir::FenvAttr fenv;
+    if (isAnyFloatingPointType(
+            mlir::cast<cir::ComplexType>(lhs.getType()).getElementType()))
+      fenv = getConstrainedFPAttr();
+    return cir::ComplexSubOp::create(*this, loc, lhs, rhs, fenv);
+  }
+
   mlir::Value createComplexConj(mlir::Location loc, mlir::Value operand) {
     return cir::ComplexConjOp::create(*this, loc, operand.getType(), operand);
   }
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td 
b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index d5fe9882e4ec8..4340e59697d11 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -6598,12 +6598,23 @@ def CIR_ComplexImagPtrOp : 
CIR_ComplexPartPtrOp<"complex.imag_ptr"> {
 
 class CIR_ComplexBinOp<string mnemonic>
     : CIR_Op<mnemonic, [Pure, SameOperandsAndResultType]> {
-  let arguments = (ins CIR_ComplexType:$lhs, CIR_ComplexType:$rhs);
+  let arguments = (ins
+    CIR_ComplexType:$lhs,
+    CIR_ComplexType:$rhs,
+    OptionalAttr<CIR_FenvAttr>:$fenv
+  );
+
   let results = (outs CIR_ComplexType:$result);
 
   let assemblyFormat = [{
     $lhs `,` $rhs `:` qualified(type($result)) attr-dict
   }];
+
+  let builders = [
+    OpBuilder<(ins "mlir::Value":$lhs, "mlir::Value":$rhs), [{
+      build($_builder, $_state, lhs, rhs, cir::FenvAttr{});
+    }]>
+  ];
 }
 
 def CIR_ComplexAddOp : CIR_ComplexBinOp<"complex.add"> {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 1fab2352b10ce..78f848733f33c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -623,7 +623,7 @@ mlir::Value ComplexExprEmitter::emitBinAdd(const BinOpInfo 
&op) {
 
   if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
       mlir::isa<cir::ComplexType>(op.rhs.getType()))
-    return cir::ComplexAddOp::create(builder, op.loc, op.lhs, op.rhs);
+    return builder.createComplexAdd(op.loc, op.lhs, op.rhs);
 
   auto createAdd = [&](mlir::Location loc, mlir::Value a, mlir::Value b) {
     return cir::isFPOrVectorOfFPType(a.getType())
@@ -651,7 +651,7 @@ mlir::Value ComplexExprEmitter::emitBinSub(const BinOpInfo 
&op) {
 
   if (mlir::isa<cir::ComplexType>(op.lhs.getType()) &&
       mlir::isa<cir::ComplexType>(op.rhs.getType()))
-    return cir::ComplexSubOp::create(builder, op.loc, op.lhs, op.rhs);
+    return builder.createComplexSub(op.loc, op.lhs, op.rhs);
 
   auto createSub = [&](mlir::Location loc, mlir::Value a, mlir::Value b) {
     return cir::isFPOrVectorOfFPType(a.getType())
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 50adaad64a763..98ad6da10c09b 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -560,6 +560,24 @@ mlir::LogicalResult lowerToConstrainedFPIntrinsic(
   return mlir::success();
 }
 
+static mlir::Value createConstrainedFPIntrinsicCall(
+    mlir::ConversionPatternRewriter &rewriter, mlir::Location loc,
+    mlir::ValueRange operands, mlir::Type llvmResTy, cir::FenvAttr fenv,
+    llvm::StringRef constrainedMnemonic, bool hasRoundingMode,
+    mlir::LLVM::FastmathFlags fastmathFlags = {}) {
+  llvm::SmallVector<mlir::Value> callOperands(operands.begin(), 
operands.end());
+  if (hasRoundingMode)
+    callOperands.push_back(createFenvMetadataValue(
+        rewriter, loc, getConstrainedRoundingMetadata(fenv)));
+  callOperands.push_back(createFenvMetadataValue(
+      rewriter, loc, getConstrainedExceptMetadata(fenv)));
+
+  mlir::LLVM::CallIntrinsicOp intrinsic = createCallLLVMIntrinsicOp(
+      rewriter, loc, "llvm.experimental.constrained." + constrainedMnemonic,
+      llvmResTy, callOperands, fastmathFlags);
+  return intrinsic->getResult(0);
+}
+
 template <typename LLVMOp>
 mlir::LogicalResult lowerConstrainableFPOp(
     mlir::Operation *op, mlir::ValueRange operands, cir::FenvAttr fenv,
@@ -5207,11 +5225,22 @@ mlir::LogicalResult 
CIRToLLVMComplexAddOpLowering::matchAndRewrite(
                                         rhsImag);
   } else {
     assert(!cir::MissingFeatures::fastMathFlags());
-    assert(!cir::MissingFeatures::fpConstraints());
-    newReal = mlir::LLVM::FAddOp::create(rewriter, loc, complexElemTy, lhsReal,
-                                         rhsReal);
-    newImag = mlir::LLVM::FAddOp::create(rewriter, loc, complexElemTy, lhsImag,
-                                         rhsImag);
+    if (cir::FenvAttr fenv = op.getFenvAttr()) {
+      newReal = createConstrainedFPIntrinsicCall(
+          rewriter, loc, {lhsReal, rhsReal}, complexElemTy, fenv,
+          /*constrainedMnemonic=*/"fadd",
+          /*hasRoundingMode=*/true);
+
+      newImag = createConstrainedFPIntrinsicCall(
+          rewriter, loc, {lhsImag, rhsImag}, complexElemTy, fenv,
+          /*constrainedMnemonic=*/"fadd",
+          /*hasRoundingMode=*/true);
+    } else {
+      newReal = mlir::LLVM::FAddOp::create(rewriter, loc, complexElemTy,
+                                           lhsReal, rhsReal);
+      newImag = mlir::LLVM::FAddOp::create(rewriter, loc, complexElemTy,
+                                           lhsImag, rhsImag);
+    }
   }
 
   mlir::Type complexLLVMTy =
@@ -5290,11 +5319,22 @@ mlir::LogicalResult 
CIRToLLVMComplexSubOpLowering::matchAndRewrite(
                                         rhsImag);
   } else {
     assert(!cir::MissingFeatures::fastMathFlags());
-    assert(!cir::MissingFeatures::fpConstraints());
-    newReal = mlir::LLVM::FSubOp::create(rewriter, loc, complexElemTy, lhsReal,
-                                         rhsReal);
-    newImag = mlir::LLVM::FSubOp::create(rewriter, loc, complexElemTy, lhsImag,
-                                         rhsImag);
+    if (cir::FenvAttr fenv = op.getFenvAttr()) {
+      newReal = createConstrainedFPIntrinsicCall(
+          rewriter, loc, {lhsReal, rhsReal}, complexElemTy, fenv,
+          /*constrainedMnemonic=*/"fsub",
+          /*hasRoundingMode=*/true);
+
+      newImag = createConstrainedFPIntrinsicCall(
+          rewriter, loc, {lhsImag, rhsImag}, complexElemTy, fenv,
+          /*constrainedMnemonic=*/"fsub",
+          /*hasRoundingMode=*/true);
+    } else {
+      newReal = mlir::LLVM::FSubOp::create(rewriter, loc, complexElemTy,
+                                           lhsReal, rhsReal);
+      newImag = mlir::LLVM::FSubOp::create(rewriter, loc, complexElemTy,
+                                           lhsImag, rhsImag);
+    }
   }
 
   mlir::Type complexLLVMTy =
@@ -5665,9 +5705,9 @@ mlir::LogicalResult 
CIRToLLVMIndirectBrOpLowering::matchAndRewrite(
   // If the poison attribute is set, use llvm.mlir.poison as the address.
   // This happens when the block has no predecessors and is essentially
   // unreachable. Do NOT erase the block argument directly, as that violates
-  // the MLIR dialect conversion framework contract (the framework tracks block
-  // arguments and will clean them up). A block with no predecessors simply
-  // produces no PHI node.
+  // the MLIR dialect conversion framework contract (the framework tracks
+  // block arguments and will clean them up). A block with no predecessors
+  // simply produces no PHI node.
   if (op.getPoison()) {
     auto llvmPtrType = mlir::LLVM::LLVMPointerType::get(rewriter.getContext());
     targetAddr =
@@ -5786,8 +5826,8 @@ mlir::LogicalResult 
CIRToLLVMMemChrOpLowering::matchAndRewrite(
   return mlir::success();
 }
 
-// Function to do the clear-padding operation. This is a faithful translation 
of
-// CGBuiltin.cpp's ClearPadding function.
+// Function to do the clear-padding operation. This is a faithful
+// translation of CGBuiltin.cpp's ClearPadding function.
 static void clearPadding(mlir::ConversionPatternRewriter &rewriter,
                          mlir::Location loc, mlir::Value inputPtr,
                          uint64_t baseAlignment,
diff --git a/clang/test/CIR/CodeGen/complex-strict-fp.cpp 
b/clang/test/CIR/CodeGen/complex-strict-fp.cpp
new file mode 100644
index 0000000000000..1b2af0ba1664c
--- /dev/null
+++ b/clang/test/CIR/CodeGen/complex-strict-fp.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -ffp-contract=on -fexperimental-strict-floating-point 
-ffp-exception-behavior=strict -emit-cir %s -o %t-strict.cir
+// RUN: FileCheck --input-file=%t-strict.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-fclangir -ffp-contract=on -fexperimental-strict-floating-point 
-ffp-exception-behavior=strict -emit-llvm %s -o %t-strict.ll
+// RUN: FileCheck --input-file=%t-strict.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value 
-ffp-contract=on -fexperimental-strict-floating-point 
-ffp-exception-behavior=strict -emit-llvm %s -o %t-strict-ogcg.ll
+// RUN: FileCheck --input-file=%t-strict-ogcg.ll %s -check-prefix=OGCG
+
+void complex_add() {
+  _Complex float a;
+  _Complex float b;
+  _Complex float c = a + b;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : 
!cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : 
!cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[C_ADDR:.*]] = cir.alloca "c" {{.*}} init : 
!cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR: %[[RESULT:.*]] = cir.complex.add %[[TMP_A]], %[[TMP_B]] : 
!cir.complex<!cir.float> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, 
except_mode = unknown, strict_except = true>}
+// CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.complex<!cir.float>, 
!cir.ptr<!cir.complex<!cir.float>>
+
+// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4
+// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, align 4
+// LLVM: %[[C_ADDR:.*]] = alloca { float, float }, align 4
+// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4
+// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4
+// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 0
+// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 1
+// LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 0
+// LLVM: %[[B_IMAG:.*]] = extractvalue { float, float } %[[TMP_B]], 1
+// LLVM: %[[RESULT_REAL:.*]] = call float 
@llvm.experimental.constrained.fadd.f32(float %[[A_REAL]], float %[[B_REAL]], 
metadata !"round.tonearest", metadata !"fpexcept.strict")
+// LLVM: %[[RESULT_IMAG:.*]] = call float 
@llvm.experimental.constrained.fadd.f32(float %[[A_IMAG]], float %[[B_IMAG]], 
metadata !"round.tonearest", metadata !"fpexcept.strict")
+// LLVM: %[[TMP_RESULT:.*]] = insertvalue { float, float } poison, float 
%[[RESULT_REAL]], 0
+// LLVM: %[[RESULT:.*]] = insertvalue { float, float } %[[TMP_RESULT]], float 
%[[RESULT_IMAG]], 1
+// LLVM: store { float, float } %[[RESULT]], ptr %[[C_ADDR]], align 4
+
+// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[C_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[A_ADDR]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
+// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[B_ADDR]], i32 0, i32 0
+// OGCG: %[[B_REAL:.*]] = load float, ptr %[[B_REAL_PTR]], align 4
+// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[B_ADDR]], i32 0, i32 1
+// OGCG: %[[B_IMAG:.*]] = load float, ptr %[[B_IMAG_PTR]], align 4
+// OGCG: %[[RESULT_REAL:.*]] = call float 
@llvm.experimental.constrained.fadd.f32(float %[[A_REAL]], float %[[B_REAL]], 
metadata !"round.tonearest", metadata !"fpexcept.strict") #2
+// OGCG: %[[RESULT_IMAG:.*]] = call float 
@llvm.experimental.constrained.fadd.f32(float %[[A_IMAG]], float %[[B_IMAG]], 
metadata !"round.tonearest", metadata !"fpexcept.strict") #2
+// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[C_ADDR]], i32 0, i32 0
+// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[C_ADDR]], i32 0, i32 1
+// OGCG: store float %[[RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4
+// OGCG: store float %[[RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4
+
+void complex_sub() {
+  _Complex float a;
+  _Complex float b;
+  _Complex float c = a - b;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : 
!cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : 
!cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[C_ADDR:.*]] = cir.alloca "c" {{.*}} init : 
!cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR: %[[TMP_B:.*]] = cir.load {{.*}} %[[B_ADDR]] : 
!cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR: %[[RESULT:.*]] = cir.complex.sub %[[TMP_A]], %[[TMP_B]] : 
!cir.complex<!cir.float> {fenv = #cir.fenv<dynamic_rounding_mode = tonearest, 
except_mode = unknown, strict_except = true>}
+// CIR: cir.store {{.*}} %[[RESULT]], %[[C_ADDR]] : !cir.complex<!cir.float>, 
!cir.ptr<!cir.complex<!cir.float>>
+
+// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, align 4
+// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, align 4
+// LLVM: %[[C_ADDR:.*]] = alloca { float, float }, align 4
+// LLVM: %[[TMP_A:.*]] = load { float, float }, ptr %[[A_ADDR]], align 4
+// LLVM: %[[TMP_B:.*]] = load { float, float }, ptr %[[B_ADDR]], align 4
+// LLVM: %[[A_REAL:.*]] = extractvalue { float, float } %[[TMP_A]], 0
+// LLVM: %[[A_IMAG:.*]] = extractvalue { float, float } %[[TMP_A]], 1
+// LLVM: %[[B_REAL:.*]] = extractvalue { float, float } %[[TMP_B]], 0
+// LLVM: %[[B_IMAG:.*]] = extractvalue { float, float } %[[TMP_B]], 1
+// LLVM: %[[RESULT_REAL:.*]] = call float 
@llvm.experimental.constrained.fsub.f32(float %[[A_REAL]], float %[[B_REAL]], 
metadata !"round.tonearest", metadata !"fpexcept.strict")
+// LLVM: %[[RESULT_IMAG:.*]] = call float 
@llvm.experimental.constrained.fsub.f32(float %[[A_IMAG]], float %[[B_IMAG]], 
metadata !"round.tonearest", metadata !"fpexcept.strict")
+// LLVM: %[[TMP_RESULT:.*]] = insertvalue { float, float } poison, float 
%[[RESULT_REAL]], 0
+// LLVM: %[[RESULT:.*]] = insertvalue { float, float } %[[TMP_RESULT]], float 
%[[RESULT_IMAG]], 1
+// LLVM: store { float, float } %[[RESULT]], ptr %[[C_ADDR]], align 4
+
+// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[C_ADDR:.*]] = alloca { float, float }, align 4
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[A_ADDR]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load float, ptr %[[A_REAL_PTR]], align 4
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
+// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[B_ADDR]], i32 0, i32 0
+// OGCG: %[[B_REAL:.*]] = load float, ptr %[[B_REAL_PTR]], align 4
+// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[B_ADDR]], i32 0, i32 1
+// OGCG: %[[B_IMAG:.*]] = load float, ptr %[[B_IMAG_PTR]], align 4
+// OGCG: %[[RESULT_REAL:.*]] = call float 
@llvm.experimental.constrained.fsub.f32(float %[[A_REAL]], float %[[B_REAL]], 
metadata !"round.tonearest", metadata !"fpexcept.strict") #2
+// OGCG: %[[RESULT_IMAG:.*]] = call float 
@llvm.experimental.constrained.fsub.f32(float %[[A_IMAG]], float %[[B_IMAG]], 
metadata !"round.tonearest", metadata !"fpexcept.strict") #2
+// OGCG: %[[C_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[C_ADDR]], i32 0, i32 0
+// OGCG: %[[C_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr 
%[[C_ADDR]], i32 0, i32 1
+// OGCG: store float %[[RESULT_REAL]], ptr %[[C_REAL_PTR]], align 4
+// OGCG: store float %[[RESULT_IMAG]], ptr %[[C_IMAG_PTR]], align 4

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

Reply via email to