diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index dc0140550382..1e5145d0e15b 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -1846,6 +1846,31 @@ def VecCreateOp : CIR_Op<"vec.create", [Pure]> { let hasVerifier = 1; } +//===----------------------------------------------------------------------===// +// VecCmp +//===----------------------------------------------------------------------===// + +def VecCmpOp : CIR_Op<"vec.cmp", [Pure, SameTypeOperands]> { + + let summary = "Compare two vectors"; + let description = [{ + The `cir.vec.cmp` operation does an element-wise comparison of two vectors + of the same type. The result is a vector of the same size as the operands + whose element type is the signed integral type that is the same size as the + element type of the operands. The values in the result are 0 or -1. + }]; + + let arguments = (ins Arg:$kind, CIR_VectorType:$lhs, + CIR_VectorType:$rhs); + let results = (outs CIR_VectorType:$result); + + let assemblyFormat = [{ + `(` $kind `,` $lhs `,` $rhs `)` `:` type($lhs) `,` type($result) attr-dict + }]; + + let hasVerifier = 0; +} + //===----------------------------------------------------------------------===// // BaseClassAddr //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 0f85e0da58dd..16056cc2b004 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -765,6 +765,26 @@ class ScalarExprEmitter : public StmtVisitor { QualType LHSTy = E->getLHS()->getType(); QualType RHSTy = E->getRHS()->getType(); + auto ClangCmpToCIRCmp = [](auto ClangCmp) -> mlir::cir::CmpOpKind { + switch (ClangCmp) { + case BO_LT: + return mlir::cir::CmpOpKind::lt; + case BO_GT: + return mlir::cir::CmpOpKind::gt; + case BO_LE: + return mlir::cir::CmpOpKind::le; + case BO_GE: + return mlir::cir::CmpOpKind::ge; + case BO_EQ: + return mlir::cir::CmpOpKind::eq; + case BO_NE: + return mlir::cir::CmpOpKind::ne; + default: + llvm_unreachable("unsupported comparison kind"); + return mlir::cir::CmpOpKind(-1); + } + }; + if (const MemberPointerType *MPT = LHSTy->getAs()) { assert(0 && "not implemented"); } else if (!LHSTy->isAnyComplexType() && !RHSTy->isAnyComplexType()) { @@ -773,12 +793,18 @@ class ScalarExprEmitter : public StmtVisitor { mlir::Value RHS = BOInfo.RHS; if (LHSTy->isVectorType()) { - // Cannot handle any vector just yet. - assert(0 && "not implemented"); - // If AltiVec, the comparison results in a numeric type, so we use - // intrinsics comparing vectors and giving 0 or 1 as a result - if (!E->getType()->isVectorType()) - assert(0 && "not implemented"); + if (!E->getType()->isVectorType()) { + // If AltiVec, the comparison results in a numeric type, so we use + // intrinsics comparing vectors and giving 0 or 1 as a result + llvm_unreachable("NYI: AltiVec comparison"); + } else { + // Other kinds of vectors. Element-wise comparison returning + // a vector. + mlir::cir::CmpOpKind Kind = ClangCmpToCIRCmp(E->getOpcode()); + return Builder.create( + CGF.getLoc(BOInfo.Loc), CGF.getCIRType(BOInfo.Ty), Kind, + BOInfo.LHS, BOInfo.RHS); + } } if (BOInfo.isFixedPointOp()) { assert(0 && "not implemented"); @@ -793,30 +819,7 @@ class ScalarExprEmitter : public StmtVisitor { llvm_unreachable("NYI"); } - mlir::cir::CmpOpKind Kind; - switch (E->getOpcode()) { - case BO_LT: - Kind = mlir::cir::CmpOpKind::lt; - break; - case BO_GT: - Kind = mlir::cir::CmpOpKind::gt; - break; - case BO_LE: - Kind = mlir::cir::CmpOpKind::le; - break; - case BO_GE: - Kind = mlir::cir::CmpOpKind::ge; - break; - case BO_EQ: - Kind = mlir::cir::CmpOpKind::eq; - break; - case BO_NE: - Kind = mlir::cir::CmpOpKind::ne; - break; - default: - llvm_unreachable("unsupported"); - } - + mlir::cir::CmpOpKind Kind = ClangCmpToCIRCmp(E->getOpcode()); return Builder.create(CGF.getLoc(BOInfo.Loc), CGF.getCIRType(BOInfo.Ty), Kind, BOInfo.LHS, BOInfo.RHS); diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 4a6e6f8af3e6..8f07d47684be 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -96,6 +96,51 @@ void walkRegionSkipping(mlir::Region ®ion, }); } +/// Convert from a CIR comparison kind to an LLVM IR integral comparison kind. +mlir::LLVM::ICmpPredicate +convertCmpKindToICmpPredicate(mlir::cir::CmpOpKind kind, bool isSigned) { + using CIR = mlir::cir::CmpOpKind; + using LLVMICmp = mlir::LLVM::ICmpPredicate; + switch (kind) { + case CIR::eq: + return LLVMICmp::eq; + case CIR::ne: + return LLVMICmp::ne; + case CIR::lt: + return (isSigned ? LLVMICmp::slt : LLVMICmp::ult); + case CIR::le: + return (isSigned ? LLVMICmp::sle : LLVMICmp::ule); + case CIR::gt: + return (isSigned ? LLVMICmp::sgt : LLVMICmp::ugt); + case CIR::ge: + return (isSigned ? LLVMICmp::sge : LLVMICmp::uge); + } + llvm_unreachable("Unknown CmpOpKind"); +} + +/// Convert from a CIR comparison kind to an LLVM IR floating-point comparison +/// kind. +mlir::LLVM::FCmpPredicate +convertCmpKindToFCmpPredicate(mlir::cir::CmpOpKind kind) { + using CIR = mlir::cir::CmpOpKind; + using LLVMFCmp = mlir::LLVM::FCmpPredicate; + switch (kind) { + case CIR::eq: + return LLVMFCmp::oeq; + case CIR::ne: + return LLVMFCmp::une; + case CIR::lt: + return LLVMFCmp::olt; + case CIR::le: + return LLVMFCmp::ole; + case CIR::gt: + return LLVMFCmp::ogt; + case CIR::ge: + return LLVMFCmp::oge; + } + llvm_unreachable("Unknown CmpOpKind"); +} + } // namespace //===----------------------------------------------------------------------===// @@ -1133,6 +1178,41 @@ class CIRVectorExtractLowering } }; +class CIRVectorCmpOpLowering + : public mlir::OpConversionPattern { +public: + using OpConversionPattern::OpConversionPattern; + + mlir::LogicalResult + matchAndRewrite(mlir::cir::VecCmpOp op, OpAdaptor adaptor, + mlir::ConversionPatternRewriter &rewriter) const override { + assert(op.getType().isa() && + op.getLhs().getType().isa() && + op.getRhs().getType().isa() && + "Vector compare with non-vector type"); + // LLVM IR vector comparison returns a vector of i1. This one-bit vector + // must be sign-extended to the correct result type. + auto elementType = + op.getLhs().getType().dyn_cast().getEltType(); + mlir::Value bitResult; + if (auto intType = elementType.dyn_cast()) { + bitResult = rewriter.create( + op.getLoc(), + convertCmpKindToICmpPredicate(op.getKind(), intType.isSigned()), + adaptor.getLhs(), adaptor.getRhs()); + } else if (elementType.isa()) { + bitResult = rewriter.create( + op.getLoc(), convertCmpKindToFCmpPredicate(op.getKind()), + adaptor.getLhs(), adaptor.getRhs()); + } else { + return op.emitError() << "unsupported type for VecCmpOp: " << elementType; + } + rewriter.replaceOpWithNewOp( + op, typeConverter->convertType(op.getType()), bitResult); + return mlir::success(); + } +}; + class CIRVAStartLowering : public mlir::OpConversionPattern { public: @@ -1835,50 +1915,6 @@ class CIRCmpOpLowering : public mlir::OpConversionPattern { public: using OpConversionPattern::OpConversionPattern; - mlir::LLVM::ICmpPredicate convertToICmpPredicate(mlir::cir::CmpOpKind kind, - bool isSigned) const { - using CIR = mlir::cir::CmpOpKind; - using LLVMICmp = mlir::LLVM::ICmpPredicate; - - switch (kind) { - case CIR::eq: - return LLVMICmp::eq; - case CIR::ne: - return LLVMICmp::ne; - case CIR::lt: - return (isSigned ? LLVMICmp::slt : LLVMICmp::ult); - case CIR::le: - return (isSigned ? LLVMICmp::sle : LLVMICmp::ule); - case CIR::gt: - return (isSigned ? LLVMICmp::sgt : LLVMICmp::ugt); - case CIR::ge: - return (isSigned ? LLVMICmp::sge : LLVMICmp::uge); - } - llvm_unreachable("Unknown CmpOpKind"); - } - - mlir::LLVM::FCmpPredicate - convertToFCmpPredicate(mlir::cir::CmpOpKind kind) const { - using CIR = mlir::cir::CmpOpKind; - using LLVMFCmp = mlir::LLVM::FCmpPredicate; - - switch (kind) { - case CIR::eq: - return LLVMFCmp::ueq; - case CIR::ne: - return LLVMFCmp::une; - case CIR::lt: - return LLVMFCmp::ult; - case CIR::le: - return LLVMFCmp::ule; - case CIR::gt: - return LLVMFCmp::ugt; - case CIR::ge: - return LLVMFCmp::uge; - } - llvm_unreachable("Unknown CmpOpKind"); - } - mlir::LogicalResult matchAndRewrite(mlir::cir::CmpOp cmpOp, OpAdaptor adaptor, mlir::ConversionPatternRewriter &rewriter) const override { @@ -1887,15 +1923,17 @@ class CIRCmpOpLowering : public mlir::OpConversionPattern { // Lower to LLVM comparison op. if (auto intTy = type.dyn_cast()) { - auto kind = convertToICmpPredicate(cmpOp.getKind(), intTy.isSigned()); + auto kind = + convertCmpKindToICmpPredicate(cmpOp.getKind(), intTy.isSigned()); llResult = rewriter.create( cmpOp.getLoc(), kind, adaptor.getLhs(), adaptor.getRhs()); } else if (auto ptrTy = type.dyn_cast()) { - auto kind = convertToICmpPredicate(cmpOp.getKind(), /* isSigned=*/false); + auto kind = convertCmpKindToICmpPredicate(cmpOp.getKind(), + /* isSigned=*/false); llResult = rewriter.create( cmpOp.getLoc(), kind, adaptor.getLhs(), adaptor.getRhs()); } else if (type.isa()) { - auto kind = convertToFCmpPredicate(cmpOp.getKind()); + auto kind = convertCmpKindToFCmpPredicate(cmpOp.getKind()); llResult = rewriter.create( cmpOp.getLoc(), kind, adaptor.getLhs(), adaptor.getRhs()); } else { @@ -2090,8 +2128,9 @@ void populateCIRToLLVMConversionPatterns(mlir::RewritePatternSet &patterns, CIRTernaryOpLowering, CIRGetMemberOpLowering, CIRSwitchOpLowering, CIRPtrDiffOpLowering, CIRCopyOpLowering, CIRMemCpyOpLowering, CIRFAbsOpLowering, CIRVTableAddrPointOpLowering, CIRVectorCreateLowering, - CIRVectorInsertLowering, CIRVectorExtractLowering, CIRStackSaveLowering, - CIRStackRestoreLowering>(converter, patterns.getContext()); + CIRVectorInsertLowering, CIRVectorExtractLowering, CIRVectorCmpOpLowering, + CIRStackSaveLowering, CIRStackRestoreLowering>(converter, + patterns.getContext()); } namespace { diff --git a/clang/test/CIR/CodeGen/vectype.cpp b/clang/test/CIR/CodeGen/vectype.cpp index 9b4fd6254b7d..d4a868183728 100644 --- a/clang/test/CIR/CodeGen/vectype.cpp +++ b/clang/test/CIR/CodeGen/vectype.cpp @@ -2,6 +2,7 @@ typedef int vi4 __attribute__((vector_size(16))); typedef double vd2 __attribute__((vector_size(16))); +typedef long long vll2 __attribute__((vector_size(16))); void vector_int_test(int x) { @@ -49,6 +50,20 @@ void vector_int_test(int x) { // CHECK: %{{[0-9]+}} = cir.unary(minus, %{{[0-9]+}}) : !cir.vector, !cir.vector vi4 n = ~a; // CHECK: %{{[0-9]+}} = cir.unary(not, %{{[0-9]+}}) : !cir.vector, !cir.vector + + // Comparisons + vi4 o = a == b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(eq, %{{[0-9]+}}, %{{[0-9]+}}) : , + vi4 p = a != b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(ne, %{{[0-9]+}}, %{{[0-9]+}}) : , + vi4 q = a < b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(lt, %{{[0-9]+}}, %{{[0-9]+}}) : , + vi4 r = a > b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(gt, %{{[0-9]+}}, %{{[0-9]+}}) : , + vi4 s = a <= b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(le, %{{[0-9]+}}, %{{[0-9]+}}) : , + vi4 t = a >= b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(ge, %{{[0-9]+}}, %{{[0-9]+}}) : , } void vector_double_test(int x, double y) { @@ -86,4 +101,18 @@ void vector_double_test(int x, double y) { // CHECK: %{{[0-9]+}} = cir.unary(plus, %{{[0-9]+}}) : !cir.vector, !cir.vector vd2 m = -a; // CHECK: %{{[0-9]+}} = cir.unary(minus, %{{[0-9]+}}) : !cir.vector, !cir.vector + + // Comparisons + vll2 o = a == b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(eq, %{{[0-9]+}}, %{{[0-9]+}}) : , + vll2 p = a != b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(ne, %{{[0-9]+}}, %{{[0-9]+}}) : , + vll2 q = a < b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(lt, %{{[0-9]+}}, %{{[0-9]+}}) : , + vll2 r = a > b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(gt, %{{[0-9]+}}, %{{[0-9]+}}) : , + vll2 s = a <= b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(le, %{{[0-9]+}}, %{{[0-9]+}}) : , + vll2 t = a >= b; + // CHECK: %{{[0-9]+}} = cir.vec.cmp(ge, %{{[0-9]+}}, %{{[0-9]+}}) : , } diff --git a/clang/test/CIR/Lowering/cmp.cir b/clang/test/CIR/Lowering/cmp.cir index 94df95173a7a..94b4b2cdd8a0 100644 --- a/clang/test/CIR/Lowering/cmp.cir +++ b/clang/test/CIR/Lowering/cmp.cir @@ -36,19 +36,19 @@ module { %23 = cir.load %2 : cir.ptr , f32 %24 = cir.load %3 : cir.ptr , f32 %25 = cir.cmp(gt, %23, %24) : f32, !cir.bool - // CHECK: llvm.fcmp "ugt" + // CHECK: llvm.fcmp "ogt" %26 = cir.load %2 : cir.ptr , f32 %27 = cir.load %3 : cir.ptr , f32 %28 = cir.cmp(eq, %26, %27) : f32, !cir.bool - // CHECK: llvm.fcmp "ueq" + // CHECK: llvm.fcmp "oeq" %29 = cir.load %2 : cir.ptr , f32 %30 = cir.load %3 : cir.ptr , f32 %31 = cir.cmp(lt, %29, %30) : f32, !cir.bool - // CHECK: llvm.fcmp "ult" + // CHECK: llvm.fcmp "olt" %32 = cir.load %2 : cir.ptr , f32 %33 = cir.load %3 : cir.ptr , f32 %34 = cir.cmp(ge, %32, %33) : f32, !cir.bool - // CHECK: llvm.fcmp "uge" + // CHECK: llvm.fcmp "oge" %35 = cir.load %2 : cir.ptr , f32 %36 = cir.load %3 : cir.ptr , f32 %37 = cir.cmp(ne, %35, %36) : f32, !cir.bool @@ -56,7 +56,7 @@ module { %38 = cir.load %2 : cir.ptr , f32 %39 = cir.load %3 : cir.ptr , f32 %40 = cir.cmp(le, %38, %39) : f32, !cir.bool - // CHECK: llvm.fcmp "ule" + // CHECK: llvm.fcmp "ole" // Pointer comparisons. %41 = cir.cmp(ne, %0, %1) : !cir.ptr, !cir.bool diff --git a/clang/test/CIR/Lowering/vectype.cpp b/clang/test/CIR/Lowering/vectype.cpp index 3557eba657e9..34458427acb3 100644 --- a/clang/test/CIR/Lowering/vectype.cpp +++ b/clang/test/CIR/Lowering/vectype.cpp @@ -4,6 +4,7 @@ typedef int vi4 __attribute__((vector_size(16))); typedef double vd2 __attribute__((vector_size(16))); +typedef long long vll2 __attribute__((vector_size(16))); void vector_int_test(int x) { @@ -124,6 +125,44 @@ void vector_int_test(int x) { // CHECK: %[[#T103:]] = llvm.insertelement %[[#T94]], %[[#T101]][%[[#T102]] : i64] : vector<4xi32> // CHECK: %[[#T104:]] = llvm.xor %[[#T103]], %[[#T93]] : vector<4xi32> // CHECK: llvm.store %[[#T104]], %[[#T29:]] : vector<4xi32>, !llvm.ptr + + // Comparisons + vi4 o = a == b; + // CHECK: %[[#T105:]] = llvm.load %[[#T3]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T106:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T107:]] = llvm.icmp "eq" %[[#T105]], %[[#T106]] : vector<4xi32> + // CHECK: %[[#T108:]] = llvm.sext %[[#T107]] : vector<4xi1> to vector<4xi32> + // CHECK: llvm.store %[[#T108]], %[[#To:]] : vector<4xi32>, !llvm.ptr + vi4 p = a != b; + // CHECK: %[[#T109:]] = llvm.load %[[#T3]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T110:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T111:]] = llvm.icmp "ne" %[[#T109]], %[[#T110]] : vector<4xi32> + // CHECK: %[[#T112:]] = llvm.sext %[[#T111]] : vector<4xi1> to vector<4xi32> + // CHECK: llvm.store %[[#T112]], %[[#Tp:]] : vector<4xi32>, !llvm.ptr + vi4 q = a < b; + // CHECK: %[[#T113:]] = llvm.load %[[#T3]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T114:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T115:]] = llvm.icmp "slt" %[[#T113]], %[[#T114]] : vector<4xi32> + // CHECK: %[[#T116:]] = llvm.sext %[[#T115]] : vector<4xi1> to vector<4xi32> + // CHECK: llvm.store %[[#T116]], %[[#Tq:]] : vector<4xi32>, !llvm.ptr + vi4 r = a > b; + // CHECK: %[[#T117:]] = llvm.load %[[#T3]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T118:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T119:]] = llvm.icmp "sgt" %[[#T117]], %[[#T118]] : vector<4xi32> + // CHECK: %[[#T120:]] = llvm.sext %[[#T119]] : vector<4xi1> to vector<4xi32> + // CHECK: llvm.store %[[#T120]], %[[#Tr:]] : vector<4xi32>, !llvm.ptr + vi4 s = a <= b; + // CHECK: %[[#T121:]] = llvm.load %[[#T3]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T122:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T123:]] = llvm.icmp "sle" %[[#T121]], %[[#T122]] : vector<4xi32> + // CHECK: %[[#T124:]] = llvm.sext %[[#T123]] : vector<4xi1> to vector<4xi32> + // CHECK: llvm.store %[[#T124]], %[[#Ts:]] : vector<4xi32>, !llvm.ptr + vi4 t = a >= b; + // CHECK: %[[#T125:]] = llvm.load %[[#T3]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T126:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<4xi32> + // CHECK: %[[#T127:]] = llvm.icmp "sge" %[[#T125]], %[[#T126]] : vector<4xi32> + // CHECK: %[[#T128:]] = llvm.sext %[[#T127]] : vector<4xi1> to vector<4xi32> + // CHECK: llvm.store %[[#T128]], %[[#Tt:]] : vector<4xi32>, !llvm.ptr } void vector_double_test(int x, double y) { @@ -155,7 +194,7 @@ void vector_double_test(int x, double y) { // Extract element. double c = a[x]; - // CHECK: 38 = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T38:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> // CHECK: %[[#T39:]] = llvm.load %[[#T1]] : !llvm.ptr -> i32 // CHECK: %[[#T40:]] = llvm.extractelement %[[#T38]][%[[#T39]] : i32] : vector<2xf64> // CHECK: llvm.store %[[#T40]], %[[#T9:]] : f64, !llvm.ptr @@ -198,4 +237,42 @@ void vector_double_test(int x, double y) { // CHECK: %[[#T58:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> // CHECK: %[[#T59:]] = llvm.fneg %[[#T58]] : vector<2xf64> // CHECK: llvm.store %[[#T59]], %[[#T21:]] : vector<2xf64>, !llvm.ptr + + // Comparisons + vll2 o = a == b; + // CHECK: %[[#T60:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T61:]] = llvm.load %[[#T7]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T62:]] = llvm.fcmp "oeq" %[[#T60]], %[[#T61]] : vector<2xf64> + // CHECK: %[[#T63:]] = llvm.sext %[[#T62]] : vector<2xi1> to vector<2xi64> + // CHECK: llvm.store %[[#T63]], %[[#To:]] : vector<2xi64>, !llvm.ptr + vll2 p = a != b; + // CHECK: %[[#T64:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T65:]] = llvm.load %[[#T7]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T66:]] = llvm.fcmp "une" %[[#T64]], %[[#T65]] : vector<2xf64> + // CHECK: %[[#T67:]] = llvm.sext %[[#T66]] : vector<2xi1> to vector<2xi64> + // CHECK: llvm.store %[[#T67]], %[[#Tp:]] : vector<2xi64>, !llvm.ptr + vll2 q = a < b; + // CHECK: %[[#T68:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T69:]] = llvm.load %[[#T7]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T70:]] = llvm.fcmp "olt" %[[#T68]], %[[#T69]] : vector<2xf64> + // CHECK: %[[#T71:]] = llvm.sext %[[#T70]] : vector<2xi1> to vector<2xi64> + // CHECK: llvm.store %[[#T71]], %[[#Tq:]] : vector<2xi64>, !llvm.ptr + vll2 r = a > b; + // CHECK: %[[#T72:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T73:]] = llvm.load %[[#T7]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T74:]] = llvm.fcmp "ogt" %[[#T72]], %[[#T73]] : vector<2xf64> + // CHECK: %[[#T75:]] = llvm.sext %[[#T74]] : vector<2xi1> to vector<2xi64> + // CHECK: llvm.store %[[#T75]], %[[#Tr:]] : vector<2xi64>, !llvm.ptr + vll2 s = a <= b; + // CHECK: %[[#T76:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T77:]] = llvm.load %[[#T7]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T78:]] = llvm.fcmp "ole" %[[#T76]], %[[#T77]] : vector<2xf64> + // CHECK: %[[#T79:]] = llvm.sext %[[#T78]] : vector<2xi1> to vector<2xi64> + // CHECK: llvm.store %[[#T79]], %[[#Ts:]] : vector<2xi64>, !llvm.ptr + vll2 t = a >= b; + // CHECK: %[[#T80:]] = llvm.load %[[#T5]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T81:]] = llvm.load %[[#T7]] : !llvm.ptr -> vector<2xf64> + // CHECK: %[[#T82:]] = llvm.fcmp "oge" %[[#T80]], %[[#T81]] : vector<2xf64> + // CHECK: %[[#T83:]] = llvm.sext %[[#T82]] : vector<2xi1> to vector<2xi64> + // CHECK: llvm.store %[[#T83]], %[[#Tt:]] : vector<2xi64>, !llvm.ptr }