llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Erich Keane (erichkeane) <details> <summary>Changes</summary> These two are lowered as if they are the expression: LHS = (LHS < RHS ) ? RHS : LHS; and LHS = (LHS < RHS ) ? LHS : RHS; This patch generates these expressions and ensures they are properly emitted into IR. Note: this is dependent on https://github.com/llvm/llvm-project/pull/163580 and cannot be merged until that one is (or the tests will fail). --- Patch is 401.91 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/163656.diff 25 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3) - (modified) clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp (+5-2) - (modified) clang/lib/Sema/SemaOpenACC.cpp (+80-13) - (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp (+532-4) - (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-float.cpp (+158-6) - (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-inline-ops.cpp (+136-6) - (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-int.cpp (+158-6) - (modified) clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-outline-ops.cpp (+137-7) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.c (+553-4) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-default-ops.cpp (+532-4) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.c (+159-6) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-float.cpp (+158-5) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-inline-ops.cpp (+136-6) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.c (+158-6) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-int.cpp (+158-6) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-outline-ops.cpp (+136-6) - (modified) clang/test/CIR/CodeGenOpenACC/compute-reduction-clause-unsigned-int.c (+158-6) - (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-default-ops.cpp (+532-4) - (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-float.cpp (+158-6) - (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-inline-ops.cpp (+136-6) - (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-int.cpp (+158-6) - (modified) clang/test/CIR/CodeGenOpenACC/loop-reduction-clause-outline-ops.cpp (+136-6) - (modified) clang/test/SemaOpenACC/combined-construct-reduction-clause.cpp (+5-3) - (modified) clang/test/SemaOpenACC/compute-construct-reduction-clause.c (+11-7) - (modified) clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp (+11-6) ``````````diff diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 40bc7b9a4e45e..a1f3292715b32 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -13670,6 +13670,9 @@ def err_acc_reduction_recipe_no_op "not have a valid operation available">; def note_acc_reduction_recipe_noop_field : Note<"while forming combiner for compound type %0">; +def note_acc_reduction_combiner_forming + : Note<"while forming %select{|binary operator '%1'|conditional " + "operator|final assignment operator}0">; // AMDGCN builtins diagnostics def err_amdgcn_load_lds_size_invalid_value : Error<"invalid size value">; diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp index f638d391d55cd..be063033ddcfc 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp @@ -590,15 +590,18 @@ void OpenACCRecipeBuilderBase::createReductionRecipeCombiner( } else { // else we have to handle each individual field after after a // get-element. + const CIRGenRecordLayout &layout = + cgf.cgm.getTypes().getCIRGenRecordLayout(rd); for (const auto &[field, combiner] : llvm::zip_equal(rd->fields(), combinerRecipes)) { mlir::Type fieldType = cgf.convertType(field->getType()); auto fieldPtr = cir::PointerType::get(fieldType); + unsigned fieldIndex = layout.getCIRFieldNo(field); mlir::Value lhsField = builder.createGetMember( - loc, fieldPtr, lhsArg, field->getName(), field->getFieldIndex()); + loc, fieldPtr, lhsArg, field->getName(), fieldIndex); mlir::Value rhsField = builder.createGetMember( - loc, fieldPtr, rhsArg, field->getName(), field->getFieldIndex()); + loc, fieldPtr, rhsArg, field->getName(), fieldIndex); emitSingleCombiner(lhsField, rhsField, combiner); } diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index ca99834ce8266..3bb8080f6e72c 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2996,6 +2996,8 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( case OpenACCReductionOperator::Max: case OpenACCReductionOperator::Min: + BinOp = BinaryOperatorKind::BO_LT; + break; case OpenACCReductionOperator::And: case OpenACCReductionOperator::Or: // We just want a 'NYI' error in the backend, so leave an empty combiner @@ -3011,26 +3013,80 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( assert(!VarTy->isArrayType() && "Only 1 level of array allowed"); + enum class CombinerFailureKind { + None = 0, + BinOp = 1, + Conditional = 2, + Assignment = 3, + }; + + auto genCombiner = [&, this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE) + -> std::pair<ExprResult, CombinerFailureKind> { + ExprResult BinOpRes = + SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, RHSDRE, + /*ForFoldExpr=*/false); + switch (ReductionOperator) { + case OpenACCReductionOperator::Addition: + case OpenACCReductionOperator::Multiplication: + case OpenACCReductionOperator::BitwiseAnd: + case OpenACCReductionOperator::BitwiseOr: + case OpenACCReductionOperator::BitwiseXOr: + // These 5 are simple and are being done as compound operators, so we can + // immediately quit here. + return {BinOpRes, BinOpRes.isUsable() ? CombinerFailureKind::None + : CombinerFailureKind::BinOp}; + case OpenACCReductionOperator::Max: + case OpenACCReductionOperator::Min: { + // These are done as: + // LHS = (LHS < RHS) ? LHS : RHS; and LHS = (LHS < RHS) ? RHS : LHS; + // + // The BinOpRes should have been created with the less-than, so we just + // have to build the conditional and assignment. + if (!BinOpRes.isUsable()) + return {BinOpRes, CombinerFailureKind::BinOp}; + + // Create the correct conditional operator, swapping the results + // (true/false value) depending on min/max. + ExprResult CondRes; + if (ReductionOperator == OpenACCReductionOperator::Min) + CondRes = SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.get(), LHSDRE, + RHSDRE); + else + CondRes = SemaRef.ActOnConditionalOp(Loc, Loc, BinOpRes.get(), RHSDRE, + LHSDRE); + + if (!CondRes.isUsable()) + return {CondRes, CombinerFailureKind::Conditional}; + + // Build assignment. + ExprResult Assignment = SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, + BinaryOperatorKind::BO_Assign, + LHSDRE, CondRes.get(), + /*ForFoldExpr=*/false); + return {Assignment, Assignment.isUsable() + ? CombinerFailureKind::None + : CombinerFailureKind::Assignment}; + } + case OpenACCReductionOperator::And: + case OpenACCReductionOperator::Or: + llvm_unreachable("And/Or not implemented, but should fail earlier"); + case OpenACCReductionOperator::Invalid: + llvm_unreachable("Invalid should have been caught above"); + } + }; + auto tryCombiner = [&, this](DeclRefExpr *LHSDRE, DeclRefExpr *RHSDRE, bool IncludeTrap) { - // TODO: OpenACC: we have to figure out based on the bin-op how to do the - // ones that we can't just use compound operators for. So &&, ||, max, and - // min aren't really clear what we could do here. if (IncludeTrap) { // Trap all of the errors here, we'll emit our own at the end. Sema::TentativeAnalysisScope Trap{SemaRef}; - - return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, - RHSDRE, - /*ForFoldExpr=*/false); - } else { - return SemaRef.BuildBinOp(SemaRef.getCurScope(), Loc, BinOp, LHSDRE, - RHSDRE, - /*ForFoldExpr=*/false); + return genCombiner(LHSDRE, RHSDRE); } + return genCombiner(LHSDRE, RHSDRE); }; struct CombinerAttemptTy { + CombinerFailureKind FailKind; VarDecl *LHS; DeclRefExpr *LHSDRE; VarDecl *RHS; @@ -3058,9 +3114,11 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( RHSDecl->getBeginLoc()}, Ty, clang::VK_LValue, RHSDecl, nullptr, NOUR_None); - ExprResult BinOpResult = tryCombiner(LHSDRE, RHSDRE, /*IncludeTrap=*/true); + std::pair<ExprResult, CombinerFailureKind> BinOpResult = + tryCombiner(LHSDRE, RHSDRE, /*IncludeTrap=*/true); - return {LHSDecl, LHSDRE, RHSDecl, RHSDRE, BinOpResult.get()}; + return {BinOpResult.second, LHSDecl, LHSDRE, RHSDecl, RHSDRE, + BinOpResult.first.get()}; }; CombinerAttemptTy TopLevelCombinerInfo = formCombiner(VarTy); @@ -3081,12 +3139,20 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( } } + auto EmitFailureNote = [&](CombinerFailureKind CFK) { + if (CFK == CombinerFailureKind::BinOp) + return Diag(Loc, diag::note_acc_reduction_combiner_forming) + << CFK << BinaryOperator::getOpcodeStr(BinOp); + return Diag(Loc, diag::note_acc_reduction_combiner_forming) << CFK; + }; + // Since the 'root' level didn't fail, the only thing that could be successful // is a struct that we decompose on its individual fields. RecordDecl *RD = VarTy->getAsRecordDecl(); if (!RD) { Diag(Loc, diag::err_acc_reduction_recipe_no_op) << VarTy; + EmitFailureNote(TopLevelCombinerInfo.FailKind); tryCombiner(TopLevelCombinerInfo.LHSDRE, TopLevelCombinerInfo.RHSDRE, /*IncludeTrap=*/false); return true; @@ -3098,6 +3164,7 @@ bool SemaOpenACC::CreateReductionCombinerRecipe( if (!FieldCombinerInfo.Op || FieldCombinerInfo.Op->containsErrors()) { Diag(Loc, diag::err_acc_reduction_recipe_no_op) << FD->getType(); Diag(FD->getBeginLoc(), diag::note_acc_reduction_recipe_noop_field) << RD; + EmitFailureNote(FieldCombinerInfo.FailKind); tryCombiner(FieldCombinerInfo.LHSDRE, FieldCombinerInfo.RHSDRE, /*IncludeTrap=*/false); return true; diff --git a/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp b/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp index ee4fffef971e0..c1c2e4b715365 100644 --- a/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp +++ b/clang/test/CIR/CodeGenOpenACC/combined-reduction-clause-default-ops.cpp @@ -161,7 +161,78 @@ void acc_combined() { // // CHECK-NEXT: } combiner { // CHECK-NEXT: ^bb0(%[[LHSARG:.*]]: !cir.ptr<!rec_DefaultOperators> {{.*}}, %[[RHSARG:.*]]: !cir.ptr<!rec_DefaultOperators> {{.*}}) -// TODO OpenACC: Expecting combination operation here +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][0] {name = "i"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][0] {name = "i"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !s32i, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !s32i +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !s32i, !cir.ptr<!s32i> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][1] {name = "u"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!u32i> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][1] {name = "u"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!u32i> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !u32i, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !u32i +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !u32i, !cir.ptr<!u32i> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][2] {name = "f"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][2] {name = "f"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !cir.float, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !cir.float +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !cir.float, !cir.ptr<!cir.float> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][3] {name = "d"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][3] {name = "d"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !cir.double, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !cir.double +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !cir.double, !cir.ptr<!cir.double> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][4] {name = "b"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.bool> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][4] {name = "b"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.bool> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: %[[LHS_CAST:.*]] = cir.cast bool_to_int %[[LHS_LOAD]] : !cir.bool -> !s32i +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: %[[RHS_CAST:.*]] = cir.cast bool_to_int %[[RHS_LOAD]] : !cir.bool -> !s32i +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_CAST]], %[[RHS_CAST]]) : !s32i, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !cir.bool +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !cir.bool, !cir.ptr<!cir.bool> +// // CHECK-NEXT: acc.yield %[[LHSARG]] : !cir.ptr<!rec_DefaultOperators> // CHECK-NEXT: } for(int i = 0; i < 5; ++i); @@ -188,7 +259,78 @@ void acc_combined() { // // CHECK-NEXT: } combiner { // CHECK-NEXT: ^bb0(%[[LHSARG:.*]]: !cir.ptr<!rec_DefaultOperators> {{.*}}, %[[RHSARG:.*]]: !cir.ptr<!rec_DefaultOperators> {{.*}}) -// TODO OpenACC: Expecting combination operation here +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][0] {name = "i"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][0] {name = "i"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!s32i> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !s32i, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!s32i>, !s32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !s32i +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !s32i, !cir.ptr<!s32i> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][1] {name = "u"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!u32i> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][1] {name = "u"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!u32i> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !u32i, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!u32i>, !u32i +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !u32i +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !u32i, !cir.ptr<!u32i> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][2] {name = "f"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][2] {name = "f"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.float> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !cir.float, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.float>, !cir.float +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !cir.float +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !cir.float, !cir.ptr<!cir.float> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][3] {name = "d"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][3] {name = "d"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.double> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_LOAD]], %[[RHS_LOAD]]) : !cir.double, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.double>, !cir.double +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }) : (!cir.bool) -> !cir.double +// CHECK-NEXT: cir.store{{.*}} %[[TERNARY]], %[[GET_MEM_LHS]] : !cir.double, !cir.ptr<!cir.double> +// +// CHECK-NEXT: %[[GET_MEM_LHS:.*]] = cir.get_member %[[LHSARG]][4] {name = "b"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.bool> +// CHECK-NEXT: %[[GET_MEM_RHS:.*]] = cir.get_member %[[RHSARG]][4] {name = "b"} : !cir.ptr<!rec_DefaultOperators> -> !cir.ptr<!cir.bool> +// CHECK-NEXT: %[[LHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: %[[LHS_CAST:.*]] = cir.cast bool_to_int %[[LHS_LOAD]] : !cir.bool -> !s32i +// CHECK-NEXT: %[[RHS_LOAD:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: %[[RHS_CAST:.*]] = cir.cast bool_to_int %[[RHS_LOAD]] : !cir.bool -> !s32i +// CHECK-NEXT: %[[CMP:.*]] = cir.cmp(lt, %[[LHS_CAST]], %[[RHS_CAST]]) : !s32i, !cir.bool +// CHECK-NEXT: %[[TERNARY:.*]] = cir.ternary(%[[CMP]], true { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_LHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: cir.yield %[[RESULT]] +// CHECK-NEXT: }, false { +// CHECK-NEXT: %[[RESULT:.*]] = cir.load{{.*}} %[[GET_MEM_RHS]] : !cir.ptr<!cir.bool>, !cir.bool +// CHECK-NEXT: cir.yield %[[R... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/163656 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
