https://github.com/Luhaocong updated https://github.com/llvm/llvm-project/pull/193215
>From 47f0b2208cce7cb01b46bb071fcc53628aa810e1 Mon Sep 17 00:00:00 2001 From: Haocong Lu <[email protected]> Date: Sat, 5 Sep 2026 13:25:08 +0800 Subject: [PATCH] [CIR] Upstream missing support for floating point unary operator - Add Support for `__bf16/Float16/bfloat16/float128` scalar pre/post increment and decrement. - Add support for float vector increment and decrement. - Add test case for `__bf16/Float16/bfloat16/double/long double/float128` unary operator with target `x86_64`. - Add test case for interger/float vector increment and decrement with target `powerpc64le + altivec`. --- clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 72 +- .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp | 5 +- clang/lib/CodeGen/CGExprScalar.cpp | 15 +- .../CIR/CodeGen/unary-inc-dec-unsupport.cpp | 11 + .../test/CIR/CodeGen/unary-inc-dec-vector.cpp | 153 ++++ clang/test/CIR/CodeGen/unary.cpp | 695 +++++++++++++++++- 6 files changed, 889 insertions(+), 62 deletions(-) create mode 100644 clang/test/CIR/CodeGen/unary-inc-dec-unsupport.cpp create mode 100644 clang/test/CIR/CodeGen/unary-inc-dec-vector.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index f7a39a9b4a8c9..55c7fe8fb974e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -682,7 +682,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { value = emitIncDecConsiderOverflowBehavior(e, value); } else { // NOTE(CIR): clang calls CreateAdd but folds this to a unary op - value = emitIncOrDec(e, input, /*nsw=*/false); + value = emitIntIncOrDec(e, input, /*nsw=*/false); } } else if (const PointerType *ptr = type->getAs<PointerType>()) { QualType type = ptr->getPointeeType(); @@ -704,32 +704,14 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { } } else if (type->isVectorType()) { if (type->hasIntegerRepresentation()) { - value = emitIncOrDec(e, input, /*nsw=*/false); + value = emitIntIncOrDec(e, input, /*nsw=*/false); } else { - cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec vector of float"); - return {}; + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, e); + value = emitFloatIncOrDec(e, input); } } else if (type->isRealFloatingType()) { CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(cgf, e); - - if (type->isHalfType() && - !cgf.getContext().getLangOpts().NativeHalfType) { - cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec half"); - return {}; - } - - if (mlir::isa<cir::SingleType, cir::DoubleType, cir::LongDoubleType>( - value.getType())) { - mlir::Location loc = cgf.getLoc(e->getExprLoc()); - auto fpType = mlir::cast<cir::FPTypeInterface>(value.getType()); - mlir::Value amount = builder.getConstFP( - loc, value.getType(), llvm::APFloat(fpType.getFloatSemantics(), 1)); - value = e->isIncrementOp() ? builder.createFAdd(loc, value, amount) - : builder.createFSub(loc, value, amount); - } else { - cgf.cgm.errorNYI(e->getSourceRange(), "Unary inc/dec other fp type"); - return {}; - } + value = emitFloatIncOrDec(e, input); } else if (type->isFixedPointType()) { value = emitFixedPointIncDec(e, value, type); } else { @@ -756,13 +738,13 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value inVal) { switch (cgf.getLangOpts().getSignedOverflowBehavior()) { case LangOptions::SOB_Defined: - return emitIncOrDec(e, inVal, /*nsw=*/false); + return emitIntIncOrDec(e, inVal, /*nsw=*/false); case LangOptions::SOB_Undefined: assert(!cir::MissingFeatures::sanitizers()); - return emitIncOrDec(e, inVal, /*nsw=*/true); + return emitIntIncOrDec(e, inVal, /*nsw=*/true); case LangOptions::SOB_Trapping: if (!e->canOverflow()) - return emitIncOrDec(e, inVal, /*nsw=*/true); + return emitIntIncOrDec(e, inVal, /*nsw=*/true); cgf.cgm.errorNYI(e->getSourceRange(), "inc/def overflow SOB_Trapping"); return {}; } @@ -828,14 +810,48 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { return builder.createOrFold<cir::MinusOp>(loc, operand, nsw); } - mlir::Value emitIncOrDec(const UnaryOperator *e, mlir::Value input, - bool nsw = false) { + mlir::Value emitIntIncOrDec(const UnaryOperator *e, mlir::Value input, + bool nsw = false) { mlir::Location loc = cgf.getLoc(e->getSourceRange().getBegin()); return e->isIncrementOp() ? builder.createOrFold<cir::IncOp>(loc, input, nsw) : builder.createOrFold<cir::DecOp>(loc, input, nsw); } + mlir::Value emitFloatIncOrDec(const UnaryOperator *e, mlir::Value input) { + assert(cir::isFPOrVectorOfFPType(input.getType()) && + "Expect floating-point operand"); + mlir::Location loc = cgf.getLoc(e->getSourceRange().getBegin()); + + if (auto vecType = mlir::dyn_cast<cir::VectorType>(input.getType())) { + mlir::Type fpScalarType = vecType.getElementType(); + auto fpInterface = mlir::cast<cir::FPTypeInterface>(fpScalarType); + mlir::Value amount = builder.getConstFP( + loc, fpScalarType, llvm::APFloat(fpInterface.getFloatSemantics(), 1)); + amount = cir::VecSplatOp::create(builder, loc, vecType, amount); + return e->isIncrementOp() ? builder.createFAdd(loc, input, amount) + : builder.createFSub(loc, input, amount); + } else { + QualType type = e->getSubExpr()->getType(); + // Another special case: half FP increment should be done via float. + if (type->isHalfType() && !cgf.getContext().getLangOpts().NativeHalfType) + input = builder.createFloatingCast(input, builder.getSingleTy()); + + auto fpInterface = mlir::cast<cir::FPTypeInterface>(input.getType()); + mlir::Value amount = + builder.getConstFP(loc, input.getType(), + llvm::APFloat(fpInterface.getFloatSemantics(), 1)); + mlir::Value output = e->isIncrementOp() + ? builder.createFAdd(loc, input, amount) + : builder.createFSub(loc, input, amount); + + if (type->isHalfType() && !cgf.getContext().getLangOpts().NativeHalfType) + output = builder.createFloatingCast(output, builder.getFp16Ty()); + + return output; + } + } + mlir::Value VisitUnaryNot(const UnaryOperator *e) { ignoreResultAssign = false; mlir::Value op = Visit(e->getSubExpr()); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 6f7509c363fd3..bd1ace8be7563 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -3201,8 +3201,9 @@ lowerIncDecOp(CIROp op, typename CIROp::Adaptor adaptor, auto maybeNSW = nswFlag(op.getNoSignedWrap()); mlir::LLVM::ConstantOp one; if (mlir::isa<cir::VectorType>(op.getType())) { - mlir::DenseIntElementsAttr oneVec = mlir::DenseIntElementsAttr::get( - mlir::cast<mlir::ShapedType>(llvmType), 1); + mlir::ShapedType shapedTy = mlir::cast<mlir::ShapedType>(llvmType); + mlir::APInt oneAP(shapedTy.getElementTypeBitWidth(), 1); + auto oneVec = mlir::DenseElementsAttr::get(shapedTy, {oneAP}); one = mlir::LLVM::ConstantOp::create(rewriter, loc, llvmType, oneVec); } else { one = mlir::LLVM::ConstantOp::create(rewriter, loc, llvmType, 1); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 8a1dd776118f5..0ceaeef3da4b4 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -3557,12 +3557,9 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, llvm::Value *amt; CodeGenFunction::CGFPOptionsRAII FPOptsRAII(CGF, E); - if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { - // Another special case: half FP increment should be done via float. If - // the input isn't already half, it may be i16. - Value *bitcast = Builder.CreateBitCast(input, CGF.CGM.HalfTy); - value = Builder.CreateFPExt(bitcast, CGF.CGM.FloatTy, "incdec.conv"); - } + // Another special case: half FP increment should be done via float. + if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) + value = Builder.CreateFPExt(value, CGF.CGM.FloatTy, "incdec.conv"); if (value->getType()->isFloatTy()) amt = llvm::ConstantFP::get(VMContext, @@ -3593,12 +3590,10 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, } value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec"); - if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) { + if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) value = Builder.CreateFPTrunc(value, CGF.CGM.HalfTy, "incdec.conv"); - value = Builder.CreateBitCast(value, input->getType()); - } - // Fixed-point types. + // Fixed-point types. } else if (type->isFixedPointType()) { // Fixed-point types are tricky. In some cases, it isn't possible to // represent a 1 or a -1 in the type at all. Piggyback off of diff --git a/clang/test/CIR/CodeGen/unary-inc-dec-unsupport.cpp b/clang/test/CIR/CodeGen/unary-inc-dec-unsupport.cpp new file mode 100644 index 0000000000000..58cf166eee2b9 --- /dev/null +++ b/clang/test/CIR/CodeGen/unary-inc-dec-unsupport.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple powerpc64le -fclangir -emit-cir -verify %s -o - + +// PPC fp128 (__ibm128) unary inc/dec is not yet supported, drop the errorNYI +// and turn this into a regular test. + +__ibm128 g; // expected-error@*:* {{ClangIR code gen Not Yet Implemented: processing of built-in type: '__ibm128'}} + +void test_pre_inc() { ++g; } +void test_pre_dec() { --g; } +void test_post_inc() { g++; } +void test_post_dec() { g--; } diff --git a/clang/test/CIR/CodeGen/unary-inc-dec-vector.cpp b/clang/test/CIR/CodeGen/unary-inc-dec-vector.cpp new file mode 100644 index 0000000000000..5b5bf72af369d --- /dev/null +++ b/clang/test/CIR/CodeGen/unary-inc-dec-vector.cpp @@ -0,0 +1,153 @@ +// RUN: %clang_cc1 -triple powerpc64le -target-feature +altivec -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple powerpc64le -target-feature +altivec -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple powerpc64le -target-feature +altivec -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +// Unary inc/dec on vector types, covering the CIRGenExprScalar.cpp vector +// branch: +// * integer vectors go through emitIntIncOrDec -> cir.inc/cir.dec +// * float vectors go through emitFloatIncOrDec -> cir.fadd/cir.fsub + +typedef int vi4 __attribute__((vector_size(16))); +typedef unsigned uvi4 __attribute__((vector_size(16))); +typedef short vsh8 __attribute__((vector_size(16))); +typedef float vf4 __attribute__((vector_size(16))); +typedef double vd2 __attribute__((vector_size(16))); + +void vecIntIncDec(vi4 a) { + ++a; + --a; + a++; + a--; +} +// CIR-LABEL: @_Z12vecIntIncDecDv4_i +// CIR: cir.inc %{{.+}} : !cir.vector<4 x !s32i> +// CIR: cir.dec %{{.+}} : !cir.vector<4 x !s32i> +// CIR: cir.inc %{{.+}} : !cir.vector<4 x !s32i> +// CIR: cir.dec %{{.+}} : !cir.vector<4 x !s32i> + +// LLVM-LABEL: @_Z12vecIntIncDecDv4_i +// LLVM: add <4 x i32> %{{.+}}, splat (i32 1) +// LLVM: sub <4 x i32> %{{.+}}, splat (i32 1) +// LLVM: add <4 x i32> %{{.+}}, splat (i32 1) +// LLVM: sub <4 x i32> %{{.+}}, splat (i32 1) + +// OGCG-LABEL: @_Z12vecIntIncDecDv4_i +// OGCG: add <4 x i32> %{{.+}}, splat (i32 1) +// OGCG: add <4 x i32> %{{.+}}, splat (i32 -1) +// OGCG: add <4 x i32> %{{.+}}, splat (i32 1) +// OGCG: add <4 x i32> %{{.+}}, splat (i32 -1) + +void vecUIntIncDec(uvi4 b) { + ++b; + --b; + b++; + b--; +} +// CIR-LABEL: @_Z13vecUIntIncDecDv4_j +// CIR: cir.inc %{{.+}} : !cir.vector<4 x !u32i> +// CIR: cir.dec %{{.+}} : !cir.vector<4 x !u32i> +// CIR: cir.inc %{{.+}} : !cir.vector<4 x !u32i> +// CIR: cir.dec %{{.+}} : !cir.vector<4 x !u32i> + +// LLVM-LABEL: @_Z13vecUIntIncDecDv4_j +// LLVM: add <4 x i32> %{{.+}}, splat (i32 1) +// LLVM: sub <4 x i32> %{{.+}}, splat (i32 1) +// LLVM: add <4 x i32> %{{.+}}, splat (i32 1) +// LLVM: sub <4 x i32> %{{.+}}, splat (i32 1) + +// OGCG-LABEL: @_Z13vecUIntIncDecDv4_j +// OGCG: add <4 x i32> %{{.+}}, splat (i32 1) +// OGCG: add <4 x i32> %{{.+}}, splat (i32 -1) +// OGCG: add <4 x i32> %{{.+}}, splat (i32 1) +// OGCG: add <4 x i32> %{{.+}}, splat (i32 -1) + +void vecShortIncDec(vsh8 c) { + ++c; + --c; + c++; + c--; +} +// CIR-LABEL: @_Z14vecShortIncDecDv8_s +// CIR: cir.inc %{{.+}} : !cir.vector<8 x !s16i> +// CIR: cir.dec %{{.+}} : !cir.vector<8 x !s16i> +// CIR: cir.inc %{{.+}} : !cir.vector<8 x !s16i> +// CIR: cir.dec %{{.+}} : !cir.vector<8 x !s16i> + +// LLVM-LABEL: @_Z14vecShortIncDecDv8_s +// LLVM: add <8 x i16> %{{.+}}, splat (i16 1) +// LLVM: sub <8 x i16> %{{.+}}, splat (i16 1) +// LLVM: add <8 x i16> %{{.+}}, splat (i16 1) +// LLVM: sub <8 x i16> %{{.+}}, splat (i16 1) + +// OGCG-LABEL: @_Z14vecShortIncDecDv8_s +// OGCG: add <8 x i16> %{{.+}}, splat (i16 1) +// OGCG: add <8 x i16> %{{.+}}, splat (i16 -1) +// OGCG: add <8 x i16> %{{.+}}, splat (i16 1) +// OGCG: add <8 x i16> %{{.+}}, splat (i16 -1) + +void vecFloatIncDec(vf4 a) { + ++a; + --a; + a++; + a--; +} +// CIR-LABEL: @_Z14vecFloatIncDecDv4_f +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.float, !cir.vector<4 x !cir.float> +// CIR: cir.fadd %{{.+}}, %[[ONEVEC]] : !cir.vector<4 x !cir.float> +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.float, !cir.vector<4 x !cir.float> +// CIR: cir.fsub %{{.+}}, %[[ONEVEC]] : !cir.vector<4 x !cir.float> +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.float, !cir.vector<4 x !cir.float> +// CIR: cir.fadd %{{.+}}, %[[ONEVEC]] : !cir.vector<4 x !cir.float> +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.float, !cir.vector<4 x !cir.float> +// CIR: cir.fsub %{{.+}}, %[[ONEVEC]] : !cir.vector<4 x !cir.float> + +// LLVM-LABEL: @_Z14vecFloatIncDecDv4_f +// LLVM: fadd <4 x float> %{{.+}}, splat (float 1.000000e+00) +// LLVM: fsub <4 x float> %{{.+}}, splat (float 1.000000e+00) +// LLVM: fadd <4 x float> %{{.+}}, splat (float 1.000000e+00) +// LLVM: fsub <4 x float> %{{.+}}, splat (float 1.000000e+00) + +// OGCG-LABEL: @_Z14vecFloatIncDecDv4_f +// OGCG: fadd <4 x float> %{{.+}}, splat (float 1.000000e+00) +// OGCG: fadd <4 x float> %{{.+}}, splat (float -1.000000e+00) +// OGCG: fadd <4 x float> %{{.+}}, splat (float 1.000000e+00) +// OGCG: fadd <4 x float> %{{.+}}, splat (float -1.000000e+00) + +void vecDoubleIncDec(vd2 b) { + ++b; + --b; + b++; + b--; +} +// CIR-LABEL: @_Z15vecDoubleIncDecDv2_d +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.double, !cir.vector<2 x !cir.double> +// CIR: cir.fadd %{{.+}}, %[[ONEVEC]] : !cir.vector<2 x !cir.double> +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.double, !cir.vector<2 x !cir.double> +// CIR: cir.fsub %{{.+}}, %[[ONEVEC]] : !cir.vector<2 x !cir.double> +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.double, !cir.vector<2 x !cir.double> +// CIR: cir.fadd %{{.+}}, %[[ONEVEC]] : !cir.vector<2 x !cir.double> +// CIR: %[[ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CIR: %[[ONEVEC:.*]] = cir.vec.splat %[[ONE]] : !cir.double, !cir.vector<2 x !cir.double> +// CIR: cir.fsub %{{.+}}, %[[ONEVEC]] : !cir.vector<2 x !cir.double> + +// LLVM-LABEL: @_Z15vecDoubleIncDecDv2_d +// LLVM: fadd <2 x double> %{{.+}}, splat (double 1.000000e+00) +// LLVM: fsub <2 x double> %{{.+}}, splat (double 1.000000e+00) +// LLVM: fadd <2 x double> %{{.+}}, splat (double 1.000000e+00) +// LLVM: fsub <2 x double> %{{.+}}, splat (double 1.000000e+00) + +// OGCG-LABEL: @_Z15vecDoubleIncDecDv2_d +// OGCG: fadd <2 x double> %{{.+}}, splat (double 1.000000e+00) +// OGCG: fadd <2 x double> %{{.+}}, splat (double -1.000000e+00) +// OGCG: fadd <2 x double> %{{.+}}, splat (double 1.000000e+00) +// OGCG: fadd <2 x double> %{{.+}}, splat (double -1.000000e+00) diff --git a/clang/test/CIR/CodeGen/unary.cpp b/clang/test/CIR/CodeGen/unary.cpp index 03b068a68d066..84a07691ce85b 100644 --- a/clang/test/CIR/CodeGen/unary.cpp +++ b/clang/test/CIR/CodeGen/unary.cpp @@ -222,6 +222,24 @@ int inc2() { // OGCG: store i32 %[[A_LOAD]], ptr %[[B]], align 4 // OGCG: %[[B_TO_OUTPUT:.*]] = load i32, ptr %[[B]], align 4 +void chars(char c) { +// CHECK: cir.func{{.*}} @_Z5charsc + + int c1 = +c; + // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i + int c2 = -c; + // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i + // CHECK: cir.minus nsw %[[PROMO]] : !s32i + + // Chars can go through some integer promotion codegen paths even when not promoted. + // These should not have nsw attributes because the intermediate promotion makes the + // overflow defined behavior. + ++c; // CHECK: cir.inc %{{.+}} : !s8i + --c; // CHECK: cir.dec %{{.+}} : !s8i + c++; // CHECK: cir.inc %{{.+}} : !s8i + c--; // CHECK: cir.dec %{{.+}} : !s8i +} + float fpPlus() { float a = 1.0f; return +a; @@ -409,65 +427,698 @@ float fpPostInc2() { // OGCG: store float %[[A_LOAD]], ptr %[[B]], align 4 // OGCG: %[[B_TO_OUTPUT:.*]] = load float, ptr %[[B]], align 4 -void chars(char c) { -// CHECK: cir.func{{.*}} @_Z5charsc +// double unary operations +double doubleUPlus(double f) { + return +f; +} - int c1 = +c; - // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i - int c2 = -c; - // CHECK: %[[PROMO:.*]] = cir.cast integral %{{.+}} : !s8i -> !s32i - // CHECK: cir.minus nsw %[[PROMO]] : !s32i +// CHECK: cir.func{{.*}} @_Z11doubleUPlusd({{.*}}) -> (!cir.double{{.*}}) +// CHECK: %[[DBL_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.double> +// CHECK: %[[DBL_LOAD:.*]] = cir.load{{.*}} %[[DBL_F]] - // Chars can go through some integer promotion codegen paths even when not promoted. - // These should not have nsw attributes because the intermediate promotion makes the - // overflow defined behavior. - ++c; // CHECK: cir.inc %{{.+}} : !s8i - --c; // CHECK: cir.dec %{{.+}} : !s8i - c++; // CHECK: cir.inc %{{.+}} : !s8i - c--; // CHECK: cir.dec %{{.+}} : !s8i +// LLVM: define{{.*}} double @_Z11doubleUPlusd({{.*}}) +// LLVM: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 + +// OGCG: define{{.*}} double @_Z11doubleUPlusd({{.*}}) +// OGCG: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 + +double doubleUMinus(double f) { + return -f; +} + +// CHECK: cir.func{{.*}} @_Z12doubleUMinusd({{.*}}) -> (!cir.double{{.*}}) +// CHECK: %[[DBL_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.double> +// CHECK: %[[DBL_LOAD:.*]] = cir.load{{.*}} %[[DBL_F]] +// CHECK: %[[DBL_NEGATED:.*]] = cir.fneg %[[DBL_LOAD]] + +// LLVM: define{{.*}} double @_Z12doubleUMinusd({{.*}}) +// LLVM: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// LLVM: %[[DBL_NEGATED:.*]] = fneg double %[[DBL_LOAD]] + +// OGCG: define{{.*}} double @_Z12doubleUMinusd({{.*}}) +// OGCG: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// OGCG: %[[DBL_NEGATED:.*]] = fneg double %[[DBL_LOAD]] + +double doubleUPreInc(double f) { + return ++f; +} + +// CHECK: cir.func{{.*}} @_Z13doubleUPreIncd({{.*}}) -> (!cir.double{{.*}}) +// CHECK: %[[DBL_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.double> +// CHECK: %[[DBL_LOAD:.*]] = cir.load{{.*}} %[[DBL_F]] +// CHECK: %[[DBL_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CHECK: %[[DBL_INC:.*]] = cir.fadd %[[DBL_LOAD]], %[[DBL_ONE]] + +// LLVM: define{{.*}} double @_Z13doubleUPreIncd({{.*}}) +// LLVM: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// LLVM: %[[DBL_INC:.*]] = fadd double %[[DBL_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} double @_Z13doubleUPreIncd({{.*}}) +// OGCG: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// OGCG: %[[DBL_INC:.*]] = fadd double %[[DBL_LOAD]], 1.000000e+00 + +double doubleUPreDec(double f) { + return --f; +} + +// CHECK: cir.func{{.*}} @_Z13doubleUPreDecd({{.*}}) -> (!cir.double{{.*}}) +// CHECK: %[[DBL_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.double> +// CHECK: %[[DBL_LOAD:.*]] = cir.load{{.*}} %[[DBL_F]] +// CHECK: %[[DBL_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CHECK: %[[DBL_DEC:.*]] = cir.fsub %[[DBL_LOAD]], %[[DBL_ONE]] + +// LLVM: define{{.*}} double @_Z13doubleUPreDecd({{.*}}) +// LLVM: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// LLVM: %[[DBL_DEC:.*]] = fsub double %[[DBL_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} double @_Z13doubleUPreDecd({{.*}}) +// OGCG: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// OGCG: %[[DBL_DEC:.*]] = fadd double %[[DBL_LOAD]], -1.000000e+00 + +double doubleUPostInc(double f) { + return f++; +} + +// CHECK: cir.func{{.*}} @_Z14doubleUPostIncd({{.*}}) -> (!cir.double{{.*}}) +// CHECK: %[[DBL_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.double> +// CHECK: %[[DBL_LOAD:.*]] = cir.load{{.*}} %[[DBL_F]] +// CHECK: %[[DBL_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CHECK: %[[DBL_INC:.*]] = cir.fadd %[[DBL_LOAD]], %[[DBL_ONE]] + +// LLVM: define{{.*}} double @_Z14doubleUPostIncd({{.*}}) +// LLVM: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// LLVM: %[[DBL_INC:.*]] = fadd double %[[DBL_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} double @_Z14doubleUPostIncd({{.*}}) +// OGCG: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// OGCG: %[[DBL_INC:.*]] = fadd double %[[DBL_LOAD]], 1.000000e+00 + +double doubleUPostDec(double f) { + return f--; +} + +// CHECK: cir.func{{.*}} @_Z14doubleUPostDecd({{.*}}) -> (!cir.double{{.*}}) +// CHECK: %[[DBL_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.double> +// CHECK: %[[DBL_LOAD:.*]] = cir.load{{.*}} %[[DBL_F]] +// CHECK: %[[DBL_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.double +// CHECK: %[[DBL_DEC:.*]] = cir.fsub %[[DBL_LOAD]], %[[DBL_ONE]] + +// LLVM: define{{.*}} double @_Z14doubleUPostDecd({{.*}}) +// LLVM: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// LLVM: %[[DBL_DEC:.*]] = fsub double %[[DBL_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} double @_Z14doubleUPostDecd({{.*}}) +// OGCG: %[[DBL_LOAD:.*]] = load double, ptr %{{.*}}, align 8 +// OGCG: %[[DBL_DEC:.*]] = fadd double %[[DBL_LOAD]], -1.000000e+00 + +// long double unary operations +long double ldUPlus(long double f) { + return +f; +} + +// CHECK: cir.func{{.*}} @_Z7ldUPluse({{.*}}) -> (!cir.long_double<!cir.f80>{{.*}}) +// CHECK: %[[LD_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.long_double<!cir.f80>> +// CHECK: %[[LD_LOAD:.*]] = cir.load{{.*}} %[[LD_F]] + +// LLVM: define{{.*}} x86_fp80 @_Z7ldUPluse({{.*}}) +// LLVM: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 + +// OGCG: define{{.*}} x86_fp80 @_Z7ldUPluse({{.*}}) +// OGCG: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 + +long double ldUMinus(long double f) { + return -f; +} + +// CHECK: cir.func{{.*}} @_Z8ldUMinuse({{.*}}) -> (!cir.long_double<!cir.f80>{{.*}}) +// CHECK: %[[LD_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.long_double<!cir.f80>> +// CHECK: %[[LD_LOAD:.*]] = cir.load{{.*}} %[[LD_F]] +// CHECK: %[[LD_NEGATED:.*]] = cir.fneg %[[LD_LOAD]] + +// LLVM: define{{.*}} x86_fp80 @_Z8ldUMinuse({{.*}}) +// LLVM: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// LLVM: %[[LD_NEGATED:.*]] = fneg x86_fp80 %[[LD_LOAD]] + +// OGCG: define{{.*}} x86_fp80 @_Z8ldUMinuse({{.*}}) +// OGCG: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// OGCG: %[[LD_NEGATED:.*]] = fneg x86_fp80 %[[LD_LOAD]] + +long double ldUPreInc(long double f) { + return ++f; +} + +// CHECK: cir.func{{.*}} @_Z9ldUPreInce({{.*}}) -> (!cir.long_double<!cir.f80>{{.*}}) +// CHECK: %[[LD_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.long_double<!cir.f80>> +// CHECK: %[[LD_LOAD:.*]] = cir.load{{.*}} %[[LD_F]] +// CHECK: %[[LD_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.long_double<!cir.f80> +// CHECK: %[[LD_INC:.*]] = cir.fadd %[[LD_LOAD]], %[[LD_ONE]] + +// LLVM: define{{.*}} x86_fp80 @_Z9ldUPreInce({{.*}}) +// LLVM: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// LLVM: %[[LD_INC:.*]] = fadd x86_fp80 %[[LD_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} x86_fp80 @_Z9ldUPreInce({{.*}}) +// OGCG: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// OGCG: %[[LD_INC:.*]] = fadd x86_fp80 %[[LD_LOAD]], 1.000000e+00 + +long double ldUPreDec(long double f) { + return --f; +} + +// CHECK: cir.func{{.*}} @_Z9ldUPreDece({{.*}}) -> (!cir.long_double<!cir.f80>{{.*}}) +// CHECK: %[[LD_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.long_double<!cir.f80>> +// CHECK: %[[LD_LOAD:.*]] = cir.load{{.*}} %[[LD_F]] +// CHECK: %[[LD_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.long_double<!cir.f80> +// CHECK: %[[LD_DEC:.*]] = cir.fsub %[[LD_LOAD]], %[[LD_ONE]] + +// LLVM: define{{.*}} x86_fp80 @_Z9ldUPreDece({{.*}}) +// LLVM: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// LLVM: %[[LD_DEC:.*]] = fsub x86_fp80 %[[LD_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} x86_fp80 @_Z9ldUPreDece({{.*}}) +// OGCG: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// OGCG: %[[LD_DEC:.*]] = fadd x86_fp80 %[[LD_LOAD]], -1.000000e+00 + +long double ldUPostInc(long double f) { + return f++; +} + +// CHECK: cir.func{{.*}} @_Z10ldUPostInce({{.*}}) -> (!cir.long_double<!cir.f80>{{.*}}) +// CHECK: %[[LD_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.long_double<!cir.f80>> +// CHECK: %[[LD_LOAD:.*]] = cir.load{{.*}} %[[LD_F]] +// CHECK: %[[LD_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.long_double<!cir.f80> +// CHECK: %[[LD_INC:.*]] = cir.fadd %[[LD_LOAD]], %[[LD_ONE]] + +// LLVM: define{{.*}} x86_fp80 @_Z10ldUPostInce({{.*}}) +// LLVM: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// LLVM: %[[LD_INC:.*]] = fadd x86_fp80 %[[LD_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} x86_fp80 @_Z10ldUPostInce({{.*}}) +// OGCG: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// OGCG: %[[LD_INC:.*]] = fadd x86_fp80 %[[LD_LOAD]], 1.000000e+00 + +long double ldUPostDec(long double f) { + return f--; +} + +// CHECK: cir.func{{.*}} @_Z10ldUPostDece({{.*}}) -> (!cir.long_double<!cir.f80>{{.*}}) +// CHECK: %[[LD_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.long_double<!cir.f80>> +// CHECK: %[[LD_LOAD:.*]] = cir.load{{.*}} %[[LD_F]] +// CHECK: %[[LD_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.long_double<!cir.f80> +// CHECK: %[[LD_DEC:.*]] = cir.fsub %[[LD_LOAD]], %[[LD_ONE]] + +// LLVM: define{{.*}} x86_fp80 @_Z10ldUPostDece({{.*}}) +// LLVM: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// LLVM: %[[LD_DEC:.*]] = fsub x86_fp80 %[[LD_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} x86_fp80 @_Z10ldUPostDece({{.*}}) +// OGCG: %[[LD_LOAD:.*]] = load x86_fp80, ptr %{{.*}}, align 16 +// OGCG: %[[LD_DEC:.*]] = fadd x86_fp80 %[[LD_LOAD]], -1.000000e+00 + +// __float128 unary operations +__float128 f128UPlus(__float128 f) { + return +f; +} + +// CHECK: cir.func{{.*}} @_Z9f128UPlusg({{.*}}) -> (!cir.f128{{.*}}) +// CHECK: %[[F128_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f128> +// CHECK: %[[F128_LOAD:.*]] = cir.load{{.*}} %[[F128_F]] + +// LLVM: define{{.*}} fp128 @_Z9f128UPlusg({{.*}}) +// LLVM: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 + +// OGCG: define{{.*}} fp128 @_Z9f128UPlusg({{.*}}) +// OGCG: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 + +__float128 f128UMinus(__float128 f) { + return -f; +} + +// CHECK: cir.func{{.*}} @_Z10f128UMinusg({{.*}}) -> (!cir.f128{{.*}}) +// CHECK: %[[F128_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f128> +// CHECK: %[[F128_LOAD:.*]] = cir.load{{.*}} %[[F128_F]] +// CHECK: %[[F128_NEG:.*]] = cir.fneg %[[F128_LOAD]] + +// LLVM: define{{.*}} fp128 @_Z10f128UMinusg({{.*}}) +// LLVM: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// LLVM: %[[F128_NEG:.*]] = fneg fp128 %[[F128_LOAD]] + +// OGCG: define{{.*}} fp128 @_Z10f128UMinusg({{.*}}) +// OGCG: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// OGCG: %[[F128_NEG:.*]] = fneg fp128 %[[F128_LOAD]] + +__float128 f128UPreInc(__float128 f) { + return ++f; +} + +// CHECK: cir.func{{.*}} @_Z11f128UPreIncg({{.*}}) -> (!cir.f128{{.*}}) +// CHECK: %[[F128_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f128> +// CHECK: %[[F128_LOAD:.*]] = cir.load{{.*}} %[[F128_F]] +// CHECK: %[[F128_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f128 +// CHECK: %[[F128_INC:.*]] = cir.fadd %[[F128_LOAD]], %[[F128_ONE]] + +// LLVM: define{{.*}} fp128 @_Z11f128UPreIncg({{.*}}) +// LLVM: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// LLVM: %[[F128_INC:.*]] = fadd fp128 %[[F128_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} fp128 @_Z11f128UPreIncg({{.*}}) +// OGCG: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// OGCG: %[[F128_INC:.*]] = fadd fp128 %[[F128_LOAD]], 1.000000e+00 + +__float128 f128UPreDec(__float128 f) { + return --f; +} + +// CHECK: cir.func{{.*}} @_Z11f128UPreDecg({{.*}}) -> (!cir.f128{{.*}}) +// CHECK: %[[F128_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f128> +// CHECK: %[[F128_LOAD:.*]] = cir.load{{.*}} %[[F128_F]] +// CHECK: %[[F128_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f128 +// CHECK: %[[F128_DEC:.*]] = cir.fsub %[[F128_LOAD]], %[[F128_ONE]] + +// LLVM: define{{.*}} fp128 @_Z11f128UPreDecg({{.*}}) +// LLVM: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// LLVM: %[[F128_DEC:.*]] = fsub fp128 %[[F128_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} fp128 @_Z11f128UPreDecg({{.*}}) +// OGCG: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// OGCG: %[[F128_DEC:.*]] = fadd fp128 %[[F128_LOAD]], -1.000000e+00 + +__float128 f128UPostInc(__float128 f) { + return f++; +} + +// CHECK: cir.func{{.*}} @_Z12f128UPostIncg({{.*}}) -> (!cir.f128{{.*}}) +// CHECK: %[[F128_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f128> +// CHECK: %[[F128_LOAD:.*]] = cir.load{{.*}} %[[F128_F]] +// CHECK: %[[F128_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f128 +// CHECK: %[[F128_INC:.*]] = cir.fadd %[[F128_LOAD]], %[[F128_ONE]] + +// LLVM: define{{.*}} fp128 @_Z12f128UPostIncg({{.*}}) +// LLVM: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// LLVM: %[[F128_INC:.*]] = fadd fp128 %[[F128_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} fp128 @_Z12f128UPostIncg({{.*}}) +// OGCG: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// OGCG: %[[F128_INC:.*]] = fadd fp128 %[[F128_LOAD]], 1.000000e+00 + +__float128 f128UPostDec(__float128 f) { + return f--; } -_Float16 fp16UPlus(_Float16 f) { +// CHECK: cir.func{{.*}} @_Z12f128UPostDecg({{.*}}) -> (!cir.f128{{.*}}) +// CHECK: %[[F128_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f128> +// CHECK: %[[F128_LOAD:.*]] = cir.load{{.*}} %[[F128_F]] +// CHECK: %[[F128_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f128 +// CHECK: %[[F128_DEC:.*]] = cir.fsub %[[F128_LOAD]], %[[F128_ONE]] + +// LLVM: define{{.*}} fp128 @_Z12f128UPostDecg({{.*}}) +// LLVM: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// LLVM: %[[F128_DEC:.*]] = fsub fp128 %[[F128_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} fp128 @_Z12f128UPostDecg({{.*}}) +// OGCG: %[[F128_LOAD:.*]] = load fp128, ptr %{{.*}}, align 16 +// OGCG: %[[F128_DEC:.*]] = fadd fp128 %[[F128_LOAD]], -1.000000e+00 + +// Float16 unary operations +_Float16 Float16UPlus(_Float16 f) { return +f; } -// CHECK: cir.func{{.*}} @_Z9fp16UPlusDF16_({{.*}}) -> (!cir.f16{{.*}}) +// CHECK: cir.func{{.*}} @_Z12Float16UPlusDF16_({{.*}}) -> (!cir.f16{{.*}}) // CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[F:.*]] // CHECK: %[[PROMOTED:.*]] = cir.cast floating %[[INPUT]] : !cir.f16 -> !cir.float // CHECK: %[[UNPROMOTED:.*]] = cir.cast floating %[[PROMOTED]] : !cir.float -> !cir.f16 -// LLVM: define{{.*}} half @_Z9fp16UPlusDF16_({{.*}}) +// LLVM: define{{.*}} half @_Z12Float16UPlusDF16_({{.*}}) // LLVM: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2 // LLVM: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float // LLVM: %[[UNPROMOTED:.*]] = fptrunc float %[[PROMOTED]] to half -// OGCG: define{{.*}} half @_Z9fp16UPlusDF16_({{.*}}) +// OGCG: define{{.*}} half @_Z12Float16UPlusDF16_({{.*}}) // OGCG: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2 // OGCG: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float // OGCG: %[[UNPROMOTED:.*]] = fptrunc float %[[PROMOTED]] to half -_Float16 fp16UMinus(_Float16 f) { +_Float16 Float16UMinus(_Float16 f) { return -f; } -// CHECK: cir.func{{.*}} @_Z10fp16UMinusDF16_({{.*}}) -> (!cir.f16{{.*}}) +// CHECK: cir.func{{.*}} @_Z13Float16UMinusDF16_({{.*}}) -> (!cir.f16{{.*}}) // CHECK: %[[INPUT:.*]] = cir.load{{.*}} %[[F:.*]] // CHECK: %[[PROMOTED:.*]] = cir.cast floating %[[INPUT]] : !cir.f16 -> !cir.float // CHECK: %[[RESULT:.*]] = cir.fneg %[[PROMOTED]] // CHECK: %[[UNPROMOTED:.*]] = cir.cast floating %[[RESULT]] : !cir.float -> !cir.f16 -// LLVM: define{{.*}} half @_Z10fp16UMinusDF16_({{.*}}) +// LLVM: define{{.*}} half @_Z13Float16UMinusDF16_({{.*}}) // LLVM: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2 // LLVM: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float // LLVM: %[[RESULT:.*]] = fneg float %[[PROMOTED]] // LLVM: %[[UNPROMOTED:.*]] = fptrunc float %[[RESULT]] to half -// OGCG: define{{.*}} half @_Z10fp16UMinusDF16_({{.*}}) +// OGCG: define{{.*}} half @_Z13Float16UMinusDF16_({{.*}}) // OGCG: %[[F_LOAD:.*]] = load half, ptr %{{.*}}, align 2 // OGCG: %[[PROMOTED:.*]] = fpext half %[[F_LOAD]] to float // OGCG: %[[RESULT:.*]] = fneg float %[[PROMOTED]] // OGCG: %[[UNPROMOTED:.*]] = fptrunc float %[[RESULT]] to half +_Float16 Float16UPreInc(_Float16 f) { + return ++f; +} + +// CHECK: cir.func{{.*}} @_Z14Float16UPreIncDF16_({{.*}}) -> (!cir.f16{{.*}}) +// CHECK: %[[PREINC_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f16> +// CHECK: %[[PREINC_INPUT:.*]] = cir.load{{.*}} %[[PREINC_F]] +// CHECK: %[[PREINC_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f16 +// CHECK: %[[PREINC_RESULT:.*]] = cir.fadd %[[PREINC_INPUT]], %[[PREINC_ONE]] : !cir.f16 + +// LLVM: define{{.*}} half @_Z14Float16UPreIncDF16_({{.*}}) +// LLVM: %[[PREINC_F_ADDR:.*]] = alloca half, align 2 +// LLVM: %[[PREINC_INPUT:.*]] = load half, ptr %[[PREINC_F_ADDR]], align 2 +// LLVM: %[[PREINC_RESULT:.*]] = fadd half %[[PREINC_INPUT]], 1.000000e+00 + +// OGCG: define{{.*}} half @_Z14Float16UPreIncDF16_({{.*}}) +// OGCG: %[[PREINC_F_ADDR:.*]] = alloca half, align 2 +// OGCG: %[[PREINC_INPUT:.*]] = load half, ptr %[[PREINC_F_ADDR]], align 2 +// OGCG: %[[PREINC_RESULT:.*]] = fadd half %[[PREINC_INPUT]], 1.000000e+00 + +_Float16 Float16UPreDec(_Float16 f) { + return --f; +} + +// CHECK: cir.func{{.*}} @_Z14Float16UPreDecDF16_({{.*}}) -> (!cir.f16{{.*}}) +// CHECK: %[[PREDEC_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f16> +// CHECK: %[[PREDEC_INPUT:.*]] = cir.load{{.*}} %[[PREDEC_F]] +// CHECK: %[[PREDEC_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f16 +// CHECK: %[[PREDEC_RESULT:.*]] = cir.fsub %[[PREDEC_INPUT]], %[[PREDEC_ONE]] : !cir.f16 + +// LLVM: define{{.*}} half @_Z14Float16UPreDecDF16_({{.*}}) +// LLVM: %[[PREDEC_F_ADDR:.*]] = alloca half, align 2 +// LLVM: %[[PREDEC_INPUT:.*]] = load half, ptr %[[PREDEC_F_ADDR]], align 2 +// LLVM: %[[PREDEC_RESULT:.*]] = fsub half %[[PREDEC_INPUT]], 1.000000e+00 + +// OGCG: define{{.*}} half @_Z14Float16UPreDecDF16_({{.*}}) +// OGCG: %[[PREDEC_F_ADDR:.*]] = alloca half, align 2 +// OGCG: %[[PREDEC_INPUT:.*]] = load half, ptr %[[PREDEC_F_ADDR]], align 2 +// OGCG: %[[PREDEC_RESULT:.*]] = fadd half %[[PREDEC_INPUT]], -1.000000e+00 + +_Float16 Float16UPostInc(_Float16 f) { + return f++; +} + +// CHECK: cir.func{{.*}} @_Z15Float16UPostIncDF16_({{.*}}) -> (!cir.f16{{.*}}) +// CHECK: %[[POSTINC_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f16> +// CHECK: %[[POSTINC_INPUT:.*]] = cir.load{{.*}} %[[POSTINC_F]] +// CHECK: %[[POSTINC_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f16 +// CHECK: %[[POSTINC_RESULT:.*]] = cir.fadd %[[POSTINC_INPUT]], %[[POSTINC_ONE]] : !cir.f16 + +// LLVM: define{{.*}} half @_Z15Float16UPostIncDF16_({{.*}}) +// LLVM: %[[POSTINC_F_ADDR:.*]] = alloca half, align 2 +// LLVM: %[[POSTINC_INPUT:.*]] = load half, ptr %[[POSTINC_F_ADDR]], align 2 +// LLVM: %[[POSTINC_RESULT:.*]] = fadd half %[[POSTINC_INPUT]], 1.000000e+00 + +// OGCG: define{{.*}} half @_Z15Float16UPostIncDF16_({{.*}}) +// OGCG: %[[POSTINC_F_ADDR:.*]] = alloca half, align 2 +// OGCG: %[[POSTINC_INPUT:.*]] = load half, ptr %[[POSTINC_F_ADDR]], align 2 +// OGCG: %[[POSTINC_RESULT:.*]] = fadd half %[[POSTINC_INPUT]], 1.000000e+00 + +_Float16 Float16UPostDec(_Float16 f) { + return f--; +} + +// CHECK: cir.func{{.*}} @_Z15Float16UPostDecDF16_({{.*}}) -> (!cir.f16{{.*}}) +// CHECK: %[[POSTDEC_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.f16> +// CHECK: %[[POSTDEC_INPUT:.*]] = cir.load{{.*}} %[[POSTDEC_F]] +// CHECK: %[[POSTDEC_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.f16 +// CHECK: %[[POSTDEC_RESULT:.*]] = cir.fsub %[[POSTDEC_INPUT]], %[[POSTDEC_ONE]] : !cir.f16 + +// LLVM: define{{.*}} half @_Z15Float16UPostDecDF16_({{.*}}) +// LLVM: %[[POSTDEC_F_ADDR:.*]] = alloca half, align 2 +// LLVM: %[[POSTDEC_INPUT:.*]] = load half, ptr %[[POSTDEC_F_ADDR]], align 2 +// LLVM: %[[POSTDEC_RESULT:.*]] = fsub half %[[POSTDEC_INPUT]], 1.000000e+00 + +// OGCG: define{{.*}} half @_Z15Float16UPostDecDF16_({{.*}}) +// OGCG: %[[POSTDEC_F_ADDR:.*]] = alloca half, align 2 +// OGCG: %[[POSTDEC_INPUT:.*]] = load half, ptr %[[POSTDEC_F_ADDR]], align 2 +// OGCG: %[[POSTDEC_RESULT:.*]] = fadd half %[[POSTDEC_INPUT]], -1.000000e+00 + +// __fp16 unary operations +void fp16PtrUPlus(__fp16 *f) { + *f = +(*f); +} + +// CHECK: cir.func{{.*}} @_Z12fp16PtrUPlusPDh({{.*}}) +// CHECK: %[[FPTR_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.ptr<!cir.f16>> +// CHECK: %[[FPTR_DEREF:.*]] = cir.load deref{{.*}} %[[FPTR_F]] +// CHECK: %[[FPTR_LOAD:.*]] = cir.load{{.*}} %[[FPTR_DEREF]] +// CHECK: %[[FPTR_PROMOTED:.*]] = cir.cast floating %[[FPTR_LOAD]] : !cir.f16 -> !cir.float +// CHECK: %[[FPTR_UNPROMOTED:.*]] = cir.cast floating %[[FPTR_PROMOTED]] : !cir.float -> !cir.f16 + +// LLVM: define{{.*}} void @_Z12fp16PtrUPlusPDh({{.*}}) +// LLVM: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// LLVM: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// LLVM: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_PROMOTED]] to half + +// OGCG: define{{.*}} void @_Z12fp16PtrUPlusPDh({{.*}}) +// OGCG: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// OGCG: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// OGCG: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_PROMOTED]] to half + +void fp16PtrUMinus(__fp16 *f) { + *f = -(*f); +} + +// CHECK: cir.func{{.*}} @_Z13fp16PtrUMinusPDh({{.*}}) +// CHECK: %[[FPTR_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.ptr<!cir.f16>> +// CHECK: %[[FPTR_DEREF:.*]] = cir.load deref{{.*}} %[[FPTR_F]] +// CHECK: %[[FPTR_LOAD:.*]] = cir.load{{.*}} %[[FPTR_DEREF]] +// CHECK: %[[FPTR_PROMOTED:.*]] = cir.cast floating %[[FPTR_LOAD]] : !cir.f16 -> !cir.float +// CHECK: %[[FPTR_NEGATED:.*]] = cir.fneg %[[FPTR_PROMOTED]] +// CHECK: %[[FPTR_UNPROMOTED:.*]] = cir.cast floating %[[FPTR_NEGATED]] : !cir.float -> !cir.f16 + +// LLVM: define{{.*}} void @_Z13fp16PtrUMinusPDh({{.*}}) +// LLVM: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// LLVM: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// LLVM: %[[FPTR_NEGATED:.*]] = fneg float %[[FPTR_PROMOTED]] +// LLVM: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_NEGATED]] to half + +// OGCG: define{{.*}} void @_Z13fp16PtrUMinusPDh({{.*}}) +// OGCG: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// OGCG: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// OGCG: %[[FPTR_NEGATED:.*]] = fneg float %[[FPTR_PROMOTED]] +// OGCG: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_NEGATED]] to half + +void fp16PtrUPreInc(__fp16 *f) { + ++(*f); +} + +// CHECK: cir.func{{.*}} @_Z14fp16PtrUPreIncPDh({{.*}}) +// CHECK: %[[FPTR_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.ptr<!cir.f16>> +// CHECK: %[[FPTR_DEREF:.*]] = cir.load deref{{.*}} %[[FPTR_F]] +// CHECK: %[[FPTR_LOAD:.*]] = cir.load{{.*}} %[[FPTR_DEREF]] +// CHECK: %[[FPTR_PROMOTED:.*]] = cir.cast floating %[[FPTR_LOAD]] : !cir.f16 -> !cir.float +// CHECK: %[[FPTR_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CHECK: %[[FPTR_INC:.*]] = cir.fadd %[[FPTR_PROMOTED]], %[[FPTR_ONE]] : !cir.float +// CHECK: %[[FPTR_UNPROMOTED:.*]] = cir.cast floating %[[FPTR_INC]] : !cir.float -> !cir.f16 + +// LLVM: define{{.*}} void @_Z14fp16PtrUPreIncPDh({{.*}}) +// LLVM: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// LLVM: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// LLVM: %[[FPTR_INC:.*]] = fadd float %[[FPTR_PROMOTED]], 1.000000e+00 +// LLVM: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_INC]] to half + +// OGCG: define{{.*}} void @_Z14fp16PtrUPreIncPDh({{.*}}) +// OGCG: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// OGCG: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// OGCG: %[[FPTR_INC:.*]] = fadd float %[[FPTR_PROMOTED]], 1.000000e+00 +// OGCG: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_INC]] to half + +void fp16PtrUPreDec(__fp16 *f) { + --(*f); +} + +// CHECK: cir.func{{.*}} @_Z14fp16PtrUPreDecPDh({{.*}}) +// CHECK: %[[FPTR_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.ptr<!cir.f16>> +// CHECK: %[[FPTR_DEREF:.*]] = cir.load deref{{.*}} %[[FPTR_F]] +// CHECK: %[[FPTR_LOAD:.*]] = cir.load{{.*}} %[[FPTR_DEREF]] +// CHECK: %[[FPTR_PROMOTED:.*]] = cir.cast floating %[[FPTR_LOAD]] : !cir.f16 -> !cir.float +// CHECK: %[[FPTR_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CHECK: %[[FPTR_DEC:.*]] = cir.fsub %[[FPTR_PROMOTED]], %[[FPTR_ONE]] : !cir.float +// CHECK: %[[FPTR_UNPROMOTED:.*]] = cir.cast floating %[[FPTR_DEC]] : !cir.float -> !cir.f16 + +// LLVM: define{{.*}} void @_Z14fp16PtrUPreDecPDh({{.*}}) +// LLVM: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// LLVM: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// LLVM: %[[FPTR_DEC:.*]] = fsub float %[[FPTR_PROMOTED]], 1.000000e+00 +// LLVM: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_DEC]] to half + +// OGCG: define{{.*}} void @_Z14fp16PtrUPreDecPDh({{.*}}) +// OGCG: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// OGCG: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// OGCG: %[[FPTR_DEC:.*]] = fadd float %[[FPTR_PROMOTED]], -1.000000e+00 +// OGCG: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_DEC]] to half + +void fp16PtrUPostInc(__fp16 *f) { + (*f)++; +} + +// CHECK: cir.func{{.*}} @_Z15fp16PtrUPostIncPDh({{.*}}) +// CHECK: %[[FPTR_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.ptr<!cir.f16>> +// CHECK: %[[FPTR_DEREF:.*]] = cir.load deref{{.*}} %[[FPTR_F]] +// CHECK: %[[FPTR_LOAD:.*]] = cir.load{{.*}} %[[FPTR_DEREF]] +// CHECK: %[[FPTR_PROMOTED:.*]] = cir.cast floating %[[FPTR_LOAD]] : !cir.f16 -> !cir.float +// CHECK: %[[FPTR_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CHECK: %[[FPTR_INC:.*]] = cir.fadd %[[FPTR_PROMOTED]], %[[FPTR_ONE]] : !cir.float +// CHECK: %[[FPTR_UNPROMOTED:.*]] = cir.cast floating %[[FPTR_DEC]] : !cir.float -> !cir.f16 + +// LLVM: define{{.*}} void @_Z15fp16PtrUPostIncPDh({{.*}}) +// LLVM: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// LLVM: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// LLVM: %[[FPTR_INC:.*]] = fadd float %[[FPTR_PROMOTED]], 1.000000e+00 +// LLVM: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_INC]] to half + +// OGCG: define{{.*}} void @_Z15fp16PtrUPostIncPDh({{.*}}) +// OGCG: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// OGCG: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// OGCG: %[[FPTR_INC:.*]] = fadd float %[[FPTR_PROMOTED]], 1.000000e+00 +// OGCG: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_INC]] to half + +void fp16PtrUPostDec(__fp16 *f) { + (*f)--; +} + +// CHECK: cir.func{{.*}} @_Z15fp16PtrUPostDecPDh({{.*}}) +// CHECK: %[[FPTR_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.ptr<!cir.f16>> +// CHECK: %[[FPTR_DEREF:.*]] = cir.load deref{{.*}} %[[FPTR_F]] +// CHECK: %[[FPTR_LOAD:.*]] = cir.load{{.*}} %[[FPTR_DEREF]] +// CHECK: %[[FPTR_PROMOTED:.*]] = cir.cast floating %[[FPTR_LOAD]] : !cir.f16 -> !cir.float +// CHECK: %[[FPTR_ONE:.*]] = cir.const #cir.fp<1.000000e+00> : !cir.float +// CHECK: %[[FPTR_DEC:.*]] = cir.fsub %[[FPTR_PROMOTED]], %[[FPTR_ONE]] : !cir.float +// CHECK: %[[FPTR_UNPROMOTED:.*]] = cir.cast floating %[[FPTR_DEC]] : !cir.float -> !cir.f16 + +// LLVM: define{{.*}} void @_Z15fp16PtrUPostDecPDh({{.*}}) +// LLVM: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// LLVM: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// LLVM: %[[FPTR_DEC:.*]] = fsub float %[[FPTR_PROMOTED]], 1.000000e+00 +// LLVM: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_DEC]] to half + +// OGCG: define{{.*}} void @_Z15fp16PtrUPostDecPDh({{.*}}) +// OGCG: %[[FPTR_LOAD:.*]] = load half, ptr %{{.*}}, align 2 +// OGCG: %[[FPTR_PROMOTED:.*]] = fpext half %[[FPTR_LOAD]] to float +// OGCG: %[[FPTR_DEC:.*]] = fadd float %[[FPTR_PROMOTED]], -1.000000e+00 +// OGCG: %[[FPTR_UNPROMOTED:.*]] = fptrunc float %[[FPTR_DEC]] to half + +// __bf16 unary operations +__bf16 bf16UPlus(__bf16 f) { + return +f; +} + +// CHECK: cir.func{{.*}} @_Z9bf16UPlusDF16b({{.*}}) -> (!cir.bf16{{.*}}) +// CHECK: %[[BF16_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.bf16> +// CHECK: %[[BF16_LOAD:.*]] = cir.load{{.*}} %[[BF16_F]] +// CHECK: %[[BF16_PROMOTED:.*]] = cir.cast floating %[[BF16_LOAD]] : !cir.bf16 -> !cir.float +// CHECK: %[[BF16_UNPROMOTED:.*]] = cir.cast floating %[[BF16_PROMOTED]] : !cir.float -> !cir.bf16 + +// LLVM: define{{.*}} bfloat @_Z9bf16UPlusDF16b({{.*}}) +// LLVM: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// LLVM: %[[BF16_PROMOTED:.*]] = fpext bfloat %[[BF16_LOAD]] to float +// LLVM: %[[BF16_UNPROMOTED:.*]] = fptrunc float %[[BF16_PROMOTED]] to bfloat + +// OGCG: define{{.*}} bfloat @_Z9bf16UPlusDF16b({{.*}}) +// OGCG: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// OGCG: %[[BF16_PROMOTED:.*]] = fpext bfloat %[[BF16_LOAD]] to float +// OGCG: %[[BF16_UNPROMOTED:.*]] = fptrunc float %[[BF16_PROMOTED]] to bfloat + +__bf16 bf16UMinus(__bf16 f) { + return -f; +} + +// CHECK: cir.func{{.*}} @_Z10bf16UMinusDF16b({{.*}}) -> (!cir.bf16{{.*}}) +// CHECK: %[[BF16_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.bf16> +// CHECK: %[[BF16_LOAD:.*]] = cir.load{{.*}} %[[BF16_F]] +// CHECK: %[[BF16_PROMOTED:.*]] = cir.cast floating %[[BF16_LOAD]] : !cir.bf16 -> !cir.float +// CHECK: %[[BF16_NEGATED:.*]] = cir.fneg %[[BF16_PROMOTED]] +// CHECK: %[[BF16_UNPROMOTED:.*]] = cir.cast floating %[[BF16_NEGATED]] : !cir.float -> !cir.bf16 + +// LLVM: define{{.*}} bfloat @_Z10bf16UMinusDF16b({{.*}}) +// LLVM: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// LLVM: %[[BF16_PROMOTED:.*]] = fpext bfloat %[[BF16_LOAD]] to float +// LLVM: %[[BF16_NEGATED:.*]] = fneg float %[[BF16_PROMOTED]] +// LLVM: %[[BF16_UNPROMOTED:.*]] = fptrunc float %[[BF16_NEGATED]] to bfloat + +// OGCG: define{{.*}} bfloat @_Z10bf16UMinusDF16b({{.*}}) +// OGCG: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// OGCG: %[[BF16_PROMOTED:.*]] = fpext bfloat %[[BF16_LOAD]] to float +// OGCG: %[[BF16_NEGATED:.*]] = fneg float %[[BF16_PROMOTED]] +// OGCG: %[[BF16_UNPROMOTED:.*]] = fptrunc float %[[BF16_NEGATED]] to bfloat + +__bf16 bf16UPreInc(__bf16 f) { + return ++f; +} + +// CHECK: cir.func{{.*}} @_Z11bf16UPreIncDF16b({{.*}}) -> (!cir.bf16{{.*}}) +// CHECK: %[[BF16_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.bf16> +// CHECK: %[[BF16_LOAD:.*]] = cir.load{{.*}} %[[BF16_F]] +// CHECK: %[[BF16_INC:.*]] = cir.fadd %[[BF16_LOAD]], %{{.*}} : !cir.bf16 + +// LLVM: define{{.*}} bfloat @_Z11bf16UPreIncDF16b({{.*}}) +// LLVM: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// LLVM: %[[BF16_INC:.*]] = fadd bfloat %[[BF16_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} bfloat @_Z11bf16UPreIncDF16b({{.*}}) +// OGCG: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// OGCG: %[[BF16_INC:.*]] = fadd bfloat %[[BF16_LOAD]], 1.000000e+00 + +__bf16 bf16UPreDec(__bf16 f) { + return --f; +} + +// CHECK: cir.func{{.*}} @_Z11bf16UPreDecDF16b({{.*}}) -> (!cir.bf16{{.*}}) +// CHECK: %[[BF16_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.bf16> +// CHECK: %[[BF16_LOAD:.*]] = cir.load{{.*}} %[[BF16_F]] +// CHECK: %[[BF16_DEC:.*]] = cir.fsub %[[BF16_LOAD]], %{{.*}} : !cir.bf16 + +// LLVM: define{{.*}} bfloat @_Z11bf16UPreDecDF16b({{.*}}) +// LLVM: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// LLVM: %[[BF16_DEC:.*]] = fsub bfloat %[[BF16_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} bfloat @_Z11bf16UPreDecDF16b({{.*}}) +// OGCG: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// OGCG: %[[BF16_DEC:.*]] = fadd bfloat %[[BF16_LOAD]], -1.000000e+00 + +__bf16 bf16UPostInc(__bf16 f) { + return f++; +} + +// CHECK: cir.func{{.*}} @_Z12bf16UPostIncDF16b({{.*}}) -> (!cir.bf16{{.*}}) +// CHECK: %[[BF16_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.bf16> +// CHECK: %[[BF16_LOAD:.*]] = cir.load{{.*}} %[[BF16_F]] +// CHECK: %[[BF16_INC:.*]] = cir.fadd %[[BF16_LOAD]], %{{.*}} : !cir.bf16 + +// LLVM: define{{.*}} bfloat @_Z12bf16UPostIncDF16b({{.*}}) +// LLVM: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// LLVM: %[[BF16_INC:.*]] = fadd bfloat %[[BF16_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} bfloat @_Z12bf16UPostIncDF16b({{.*}}) +// OGCG: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// OGCG: %[[BF16_INC:.*]] = fadd bfloat %[[BF16_LOAD]], 1.000000e+00 + +__bf16 bf16UPostDec(__bf16 f) { + return f--; +} + +// CHECK: cir.func{{.*}} @_Z12bf16UPostDecDF16b({{.*}}) -> (!cir.bf16{{.*}}) +// CHECK: %[[BF16_F:.*]] = cir.alloca "f" {{.*}} init : !cir.ptr<!cir.bf16> +// CHECK: %[[BF16_LOAD:.*]] = cir.load{{.*}} %[[BF16_F]] +// CHECK: %[[BF16_DEC:.*]] = cir.fsub %[[BF16_LOAD]], %{{.*}} : !cir.bf16 + +// LLVM: define{{.*}} bfloat @_Z12bf16UPostDecDF16b({{.*}}) +// LLVM: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// LLVM: %[[BF16_DEC:.*]] = fsub bfloat %[[BF16_LOAD]], 1.000000e+00 + +// OGCG: define{{.*}} bfloat @_Z12bf16UPostDecDF16b({{.*}}) +// OGCG: %[[BF16_LOAD:.*]] = load bfloat, ptr %{{.*}}, align 2 +// OGCG: %[[BF16_DEC:.*]] = fadd bfloat %[[BF16_LOAD]], -1.000000e+00 + void test_logical_not() { int a = 5; a = !a; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
