llvm.org GIT mirror llvm / f72fb67
Extend the vcmp/fcmp LLVM IR instructions to take vectors as arguments and, if so, to return a vector of boolean as a result; Extend the select LLVM IR instruction to allow you to specify a result type which is a vector of boolean, in which case the result will be an element-wise selection instead of choosing one vector or the other; and Update LangRef.html to describe these changes. This patch was contributed by Preston Gurd! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55969 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 12 years ago
10 changed file(s) with 185 addition(s) and 51 deletion(s). Raw diff Collapse all Expand all
38453845
38463846
38473847
Syntax:
3848
  <result> = icmp <cond> <ty> <op1>, <op2>   ; yields {i1}:result

                  
                
3849
3850
Overview:
3851

The 'icmp' instruction returns a boolean value based on comparison

3852 of its two integer or pointer operands.>
3848
  <result> = icmp <cond> <ty> <op1>, <op2>   ; yields {i1} or {<N x i1>}:result>
                  
                
3849
3850
Overview:
3851

The 'icmp' instruction returns a boolean value or

3852 a vector of boolean values based on comparison
3853 of its two integer, integer vector, or pointer operands.

38533854
Arguments:
38543855

The 'icmp' instruction takes three operands. The first operand is

38553856 the condition code indicating the kind of comparison to perform. It is not
38673868
  • sle: signed less or equal
  • 38683869
    38693870

    The remaining two arguments must be integer or

    3870 pointer typed. They must also be identical types.

    3871 pointer
    3872 or integer vector typed.
    3873 They must also be identical types.

    38713874
    Semantics:
    38723875

    The 'icmp' compares op1 and op2 according to

    38733876 the condition code given as cond. The comparison performed always
    3874 yields a i1> result, as follows:
    3877 yields either an i1 or vector of i1> result, as follows:
    38753878
    38763879
  • eq: yields true if the operands are equal,
  • 38773880 false otherwise. No sign interpretation is necessary or performed.
    38973900
    38983901

    If the operands are pointer typed, the pointer

    38993902 values are compared as if they were integers.

    3903

    If the operands are integer vectors, then they are compared

    3904 element by element. The result is an i1 vector with
    3905 the same number of elements as the values being compared.
    3906 Otherwise, the result is an i1.
    3907

    39003908
    39013909
    Example:
    39023910
      <result> = icmp eq i32 4, 5          ; yields: result=false
    
                      
                    
    39133921
    39143922
    39153923
    Syntax:
    3916
      <result> = fcmp <cond> <ty> <op1>, <op2>     ; yields {i1}:result
    
                      
                    
    3917
    3918
    Overview:
    3919

    The 'fcmp' instruction returns a boolean value based on comparison

    3920 of its floating point operands.>
    3924
      <result> = fcmp <cond> <ty> <op1>, <op2>     ; yields {i1} or {<N x i1>}:result>
                      
                    
    3925
    3926
    Overview:
    3927

    The 'fcmp' instruction returns a boolean value

    3928 or vector of boolean values based on comparison
    3929 of its operands.
    3930

    3931 If the operands are floating point scalars, then the result
    3932 type is a boolean (i1).
    3933

    3934

    If the operands are floating point vectors, then the result type

    3935 is a vector of boolean with the same number of elements as the
    3936 operands being compared.

    39213937
    Arguments:
    39223938

    The 'fcmp' instruction takes three operands. The first operand is

    39233939 the condition code indicating the kind of comparison to perform. It is not
    39423958
    39433959

    Ordered means that neither operand is a QNAN while

    39443960 unordered means that either operand may be a QNAN.

    3945

    The val1 and val2 arguments must be

    3946 floating point typed. They must have identical
    3947 types.

    3961

    Each of val1 and val2 arguments must be

    3962 either a floating point type
    3963 or a vector of floating point type.
    3964 They must have identical types.

    39483965
    Semantics:
    39493966

    The 'fcmp' instruction compares op1 and op2

    3950 according to the condition code given as cond. The comparison performed
    3951 always yields a i1 result, as follows:
    3967 according to the condition code given as cond.
    3968 If the operands are vectors, then the vectors are compared
    3969 element by element.
    3970 Each comparison performed
    3971 always yields an i1 result, as follows:
    39523972
    39533973
  • false: always yields false, regardless of operands.
  • 39543974
  • oeq: yields true if both operands are not a QNAN and
  • 39824002
    39834003
    Example:
    39844004
      <result> = fcmp oeq float 4.0, 5.0    ; yields: result=false
    
                      
                    
    3985 <result> = icmp one float 4.0, 5.0 ; yields: result=true
    3986 <result> = icmp olt float 4.0, 5.0 ; yields: result=true
    3987 <result> = icmp ueq double 1.0, 2.0 ; yields: result=false
    4005 <result> = fcmp one float 4.0, 5.0 ; yields: result=true
    4006 <result> = fcmp olt float 4.0, 5.0 ; yields: result=true
    4007 <result> = fcmp ueq double 1.0, 2.0 ; yields: result=false
    39884008
    39894009
    39904010
    40154035
  • slt: signed less than
  • 40164036
  • sle: signed less or equal
  • 40174037
    4018

    The remaining two arguments must be vector of

    4038

    The remaining two arguments must be vector or

    40194039 integer typed. They must also be identical types.

    40204040
    Semantics:
    40214041

    The 'vicmp' instruction compares op1 and op2

    41394159
    Syntax:
    41404160
    41414161
    
                      
                    
    4142 <result> = select i1 <cond>, <ty> <val1>, <ty> <val2> ; yields ty
    4162 <result> = select selty <cond>, <ty> <val1>, <ty> <val2> ; yields ty
    4163
    4164 selty is either i1 or {<N x i1>}
    41434165
    41444166
    41454167
    Overview:
    41534175
    Arguments:
    41544176
    41554177

    4156 The 'select' instruction requires an 'i1' value indicating the
    4178 The 'select' instruction requires an 'i1' value or
    4179 a vector of 'i1' values indicating the
    41574180 condition, and two values of the same first class
    4158 type. If the val1/val2 are vectors, the entire vectors are selected, not
    4181 type. If the val1/val2 are vectors and
    4182 the condition is a scalar, then entire vectors are selected, not
    41594183 individual elements.
    41604184

    41614185
    41624186
    Semantics:
    41634187
    41644188

    4165 If the i1 condition evaluates is 1, the instruction returns the first
    4189 If the condition is an i1 and it evaluates to 1, the instruction returns the first
    41664190 value argument; otherwise, it returns the second value argument.
    4191

    4192

    4193 If the condition is a vector of i1, then the value arguments must
    4194 be vectors of the same size, and the selection is done element
    4195 by element.
    41674196

    41684197
    41694198
    Example:
    204204 // FIXME: Remove GETRESULT in favor of EXTRACTVAL in LLVM 3.0
    205205 FUNC_CODE_INST_GETRESULT = 25, // GETRESULT: [ty, opval, n]
    206206 FUNC_CODE_INST_EXTRACTVAL = 26, // EXTRACTVAL: [n x operands]
    207 FUNC_CODE_INST_INSERTVAL = 27 // INSERTVAL: [n x operands]
    207 FUNC_CODE_INST_INSERTVAL = 27, // INSERTVAL: [n x operands]
    208 // fcmp/icmp returning vector of Int1Ty, NOT for vicmp/vfcmp
    209 FUNC_CODE_INST_VCMP = 28 // VCMP: [opty, opval, opval, pred]
    208210 };
    209211 } // End bitc namespace
    210212 } // End llvm namespace
    1717
    1818 #include "llvm/Instruction.h"
    1919 #include "llvm/OperandTraits.h"
    20 #include "llvm/DerivedTypes.h"
    2021
    2122 namespace llvm {
    2223
    731732 static inline bool classof(const Value *V) {
    732733 return isa(V) && classof(cast(V));
    733734 }
    735 /// @brief Create a result type for fcmp/icmp (but not vicmp/vfcmp)
    736 static const Type* makeCmpResultType(const Type* opnd_type) {
    737 if (const VectorType* vt = dyn_cast(opnd_type)) {
    738 return VectorType::get(Type::Int1Ty, vt->getNumElements());
    739 }
    740 return Type::Int1Ty;
    741 }
    734742 /// Backward-compatible interfaces
    735743 /// @deprecated in 2.4, do not use, will disappear soon
    736744 static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1,
    620620 Value *RHS, ///< The right-hand-side of the expression
    621621 const std::string &NameStr = "", ///< Name of the instruction
    622622 Instruction *InsertBefore = 0 ///< Where to insert
    623 ) : CmpInst(Type::Int1Ty, Instruction::ICmp, pred, LHS, RHS, NameStr,
    623 ) : CmpInst(makeCmpResultType(LHS->getType()),
    624 Instruction::ICmp, pred, LHS, RHS, NameStr,
    624625 InsertBefore) {
    625626 assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
    626627 pred <= CmpInst::LAST_ICMP_PREDICATE &&
    628629 assert(getOperand(0)->getType() == getOperand(1)->getType() &&
    629630 "Both operands to ICmp instruction are not of the same type!");
    630631 // Check that the operands are the right type
    631 assert((getOperand(0)->getType()->isInteger() ||
    632 assert((getOperand(0)->getType()->isIntOrIntVector() ||
    632633 isa(getOperand(0)->getType())) &&
    633634 "Invalid operand types for ICmp instruction");
    634635 }
    640641 Value *RHS, ///< The right-hand-side of the expression
    641642 const std::string &NameStr, ///< Name of the instruction
    642643 BasicBlock *InsertAtEnd ///< Block to insert into.
    643 ) : CmpInst(Type::Int1Ty, Instruction::ICmp, pred, LHS, RHS, NameStr,
    644 ) : CmpInst(makeCmpResultType(LHS->getType()),
    645 Instruction::ICmp, pred, LHS, RHS, NameStr,
    644646 InsertAtEnd) {
    645647 assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
    646648 pred <= CmpInst::LAST_ICMP_PREDICATE &&
    648650 assert(getOperand(0)->getType() == getOperand(1)->getType() &&
    649651 "Both operands to ICmp instruction are not of the same type!");
    650652 // Check that the operands are the right type
    651 assert((getOperand(0)->getType()->isInteger() ||
    653 assert((getOperand(0)->getType()->isIntOrIntVector() ||
    652654 isa(getOperand(0)->getType())) &&
    653655 "Invalid operand types for ICmp instruction");
    654656 }
    753755 static inline bool classof(const Value *V) {
    754756 return isa(V) && classof(cast(V));
    755757 }
    758
    756759 };
    757760
    758761 //===----------------------------------------------------------------------===//
    772775 Value *RHS, ///< The right-hand-side of the expression
    773776 const std::string &NameStr = "", ///< Name of the instruction
    774777 Instruction *InsertBefore = 0 ///< Where to insert
    775 ) : CmpInst(Type::Int1Ty, Instruction::FCmp, pred, LHS, RHS, NameStr,
    778 ) : CmpInst(makeCmpResultType(LHS->getType()),
    779 Instruction::FCmp, pred, LHS, RHS, NameStr,
    776780 InsertBefore) {
    777781 assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
    778782 "Invalid FCmp predicate value");
    779783 assert(getOperand(0)->getType() == getOperand(1)->getType() &&
    780784 "Both operands to FCmp instruction are not of the same type!");
    781785 // Check that the operands are the right type
    782 assert(getOperand(0)->getType()->isFloatingPoint() &&
    786 assert(getOperand(0)->getType()->isFPOrFPVector() &&
    783787 "Invalid operand types for FCmp instruction");
    784788 }
    785789
    790794 Value *RHS, ///< The right-hand-side of the expression
    791795 const std::string &NameStr, ///< Name of the instruction
    792796 BasicBlock *InsertAtEnd ///< Block to insert into.
    793 ) : CmpInst(Type::Int1Ty, Instruction::FCmp, pred, LHS, RHS, NameStr,
    797 ) : CmpInst(makeCmpResultType(LHS->getType()),
    798 Instruction::FCmp, pred, LHS, RHS, NameStr,
    794799 InsertAtEnd) {
    795800 assert(pred <= FCmpInst::LAST_FCMP_PREDICATE &&
    796801 "Invalid FCmp predicate value");
    797802 assert(getOperand(0)->getType() == getOperand(1)->getType() &&
    798803 "Both operands to FCmp instruction are not of the same type!");
    799804 // Check that the operands are the right type
    800 assert(getOperand(0)->getType()->isFloatingPoint() &&
    805 assert(getOperand(0)->getType()->isFPOrFPVector() &&
    801806 "Invalid operand types for FCmp instruction");
    802807 }
    803808
    836841 static inline bool classof(const Value *V) {
    837842 return isa(V) && classof(cast(V));
    838843 }
    844
    839845 };
    840846
    841847 //===----------------------------------------------------------------------===//
    11011101 %token ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
    11021102 %token SHL LSHR ASHR
    11031103
    1104 %token ICMP FCMP VICMP VFCMP
    1104 %token ICMP FCMP VICMP VFCMP
    11051105 %type IPredicates
    11061106 %type FPredicates
    11071107 %token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
    30963096 | ICMP IPredicates Types ValueRef ',' ValueRef {
    30973097 if (!UpRefs.empty())
    30983098 GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
    3099 if (isa((*$3).get()))
    3100 GEN_ERROR("Vector types not supported by icmp instruction");
    31013099 Value* tmpVal1 = getVal(*$3, $4);
    31023100 CHECK_FOR_ERROR
    31033101 Value* tmpVal2 = getVal(*$3, $6);
    31103108 | FCMP FPredicates Types ValueRef ',' ValueRef {
    31113109 if (!UpRefs.empty())
    31123110 GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
    3113 if (isa((*$3).get()))
    3114 GEN_ERROR("Vector types not supported by fcmp instruction");
    31153111 Value* tmpVal1 = getVal(*$3, $4);
    31163112 CHECK_FOR_ERROR
    31173113 Value* tmpVal2 = getVal(*$3, $6);
    31323128 CHECK_FOR_ERROR
    31333129 $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
    31343130 if ($$ == 0)
    3135 GEN_ERROR("icmp operator returned null");
    3131 GEN_ERROR("vicmp operator returned null");
    31363132 delete $3;
    31373133 }
    31383134 | VFCMP FPredicates Types ValueRef ',' ValueRef {
    31463142 CHECK_FOR_ERROR
    31473143 $$ = CmpInst::Create($1, $2, tmpVal1, tmpVal2);
    31483144 if ($$ == 0)
    3149 GEN_ERROR("fcmp operator returned null");
    3145 GEN_ERROR("vfcmp operator returned null");
    31503146 delete $3;
    31513147 }
    31523148 | CastOps ResolvedVal TO Types {
    31623158 delete $4;
    31633159 }
    31643160 | SELECT ResolvedVal ',' ResolvedVal ',' ResolvedVal {
    3165 if ($2->getType() != Type::Int1Ty)
    3166 GEN_ERROR("select condition must be boolean");
    3161 if (isa($2->getType())) {
    3162 // vector select
    3163 if (!isa($4->getType())
    3164 || !isa($6->getType()) )
    3165 GEN_ERROR("vector select value types must be vector types");
    3166 const VectorType* cond_type = cast($2->getType());
    3167 const VectorType* select_type = cast($4->getType());
    3168 if (cond_type->getElementType() != Type::Int1Ty)
    3169 GEN_ERROR("vector select condition element type must be boolean");
    3170 if (cond_type->getNumElements() != select_type->getNumElements())
    3171 GEN_ERROR("vector select number of elements must be the same");
    3172 } else {
    3173 if ($2->getType() != Type::Int1Ty)
    3174 GEN_ERROR("select condition must be boolean");
    3175 }
    31673176 if ($4->getType() != $6->getType())
    3168 GEN_ERROR("select value types should match");
    3177 GEN_ERROR("select value types must match");
    31693178 $$ = SelectInst::Create($2, $4, $6);
    31703179 CHECK_FOR_ERROR
    31713180 }
    14981498 Value *TrueVal, *FalseVal, *Cond;
    14991499 if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) ||
    15001500 getValue(Record, OpNum, TrueVal->getType(), FalseVal) ||
    1501 getValue(Record, OpNum, Type::Int1Ty, Cond))
    1501 getValue(Record, OpNum, 0 /*skip type check*/, Cond))
    15021502 return Error("Invalid SELECT record");
    1503
    1504 // select condition can be either i1 or [N x i1]
    1505 if (const VectorType* vector_type = dyn_cast(Cond->getType())) {
    1506 // expect
    1507 if (vector_type->getElementType() != Type::Int1Ty)
    1508 return Error("Invalid SELECT condition type");
    1509 } else {
    1510 // expect i1
    1511 if (Cond->getType() != Type::Int1Ty)
    1512 return Error("Invalid SELECT condition type");
    1513 }
    15031514
    15041515 I = SelectInst::Create(Cond, TrueVal, FalseVal);
    15051516 break;
    15601571 I = new VFCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
    15611572 else
    15621573 I = new VICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
    1574 break;
    1575 }
    1576 case bitc::FUNC_CODE_INST_VCMP: { // VCMP: [opty, opval, opval, pred]
    1577 // Fcmp/ICmp returning vector of bool
    1578 unsigned OpNum = 0;
    1579 Value *LHS, *RHS;
    1580 if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
    1581 getValue(Record, OpNum, LHS->getType(), RHS) ||
    1582 OpNum+1 != Record.size())
    1583 return Error("Invalid VCMP record");
    1584
    1585 // will always be vector
    1586 if (LHS->getType()->isFPOrFPVector())
    1587 I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
    1588 else
    1589 I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
    15631590 break;
    15641591 }
    15651592 case bitc::FUNC_CODE_INST_GETRESULT: { // GETRESULT: [ty, val, n]
    640640 case Instruction::FCmp:
    641641 case Instruction::VICmp:
    642642 case Instruction::VFCmp:
    643 Code = bitc::CST_CODE_CE_CMP;
    643 if (isa(C->getOperand(0)->getType())
    644 && (CE->getOpcode() == Instruction::ICmp
    645 || CE->getOpcode() == Instruction::FCmp)) {
    646 // compare returning vector of Int1Ty
    647 assert(0 && "Unsupported constant!");
    648 } else {
    649 Code = bitc::CST_CODE_CE_CMP;
    650 }
    644651 Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
    645652 Record.push_back(VE.getValueID(C->getOperand(0)));
    646653 Record.push_back(VE.getValueID(C->getOperand(1)));
    764771 case Instruction::FCmp:
    765772 case Instruction::VICmp:
    766773 case Instruction::VFCmp:
    767 Code = bitc::FUNC_CODE_INST_CMP;
    774 if (isa(I.getOperand(0)->getType())
    775 && (I.getOpcode() == Instruction::ICmp
    776 || I.getOpcode() == Instruction::FCmp)) {
    777 // compare returning vector of Int1Ty
    778 Code = bitc::FUNC_CODE_INST_VCMP;
    779 } else {
    780 Code = bitc::FUNC_CODE_INST_CMP;
    781 }
    768782 PushValueAndType(I.getOperand(0), InstID, Vals, VE);
    769783 Vals.push_back(VE.getValueID(I.getOperand(1)));
    770784 Vals.push_back(cast(I).getPredicate());
    658658 }
    659659
    660660 void Verifier::visitSelectInst(SelectInst &SI) {
    661 Assert1(SI.getCondition()->getType() == Type::Int1Ty,
    662 "Select condition type must be bool!", &SI);
    661 if (const VectorType* vt
    662 = dyn_cast(SI.getCondition()->getType())) {
    663 Assert1( vt->getElementType() == Type::Int1Ty,
    664 "Select condition type must be vector of bool!", &SI);
    665 if (const VectorType* val_vt
    666 = dyn_cast(SI.getTrueValue()->getType())) {
    667 Assert1( vt->getNumElements() == val_vt->getNumElements(),
    668 "Select vector size != value vector size", &SI);
    669 } else {
    670 Assert1(0, "Vector select values must have vector types", &SI);
    671 }
    672 } else {
    673 Assert1(SI.getCondition()->getType() == Type::Int1Ty,
    674 "Select condition type must be bool!", &SI);
    675 }
    663676 Assert1(SI.getTrueValue()->getType() == SI.getFalseValue()->getType(),
    664677 "Select values must have identical types!", &SI);
    665678 Assert1(SI.getTrueValue()->getType() == SI.getType(),
    10271040 Assert1(Op0Ty == Op1Ty,
    10281041 "Both operands to ICmp instruction are not of the same type!", &IC);
    10291042 // Check that the operands are the right type
    1030 Assert1(Op0Ty->isInteger() || isa(Op0Ty),
    1043 Assert1(Op0Ty->isIntOrIntVector() || isa(Op0Ty),
    10311044 "Invalid operand types for ICmp instruction", &IC);
    10321045 visitInstruction(IC);
    10331046 }
    10391052 Assert1(Op0Ty == Op1Ty,
    10401053 "Both operands to FCmp instruction are not of the same type!", &FC);
    10411054 // Check that the operands are the right type
    1042 Assert1(Op0Ty->isFloatingPoint(),
    1055 Assert1(Op0Ty->isFPOrFPVector(),
    10431056 "Invalid operand types for FCmp instruction", &FC);
    10441057 visitInstruction(FC);
    10451058 }
    0 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep {icmp slt}
    1 ; rudimentary test of fcmp/icmp on vectors returning vector of bool
    2
    3 define <4 x i1> @ffoo(<4 x float> %a, <4 x float> %b) nounwind {
    4 entry:
    5 %cmp = fcmp olt <4 x float> %a, %b ; <4 x i1> [#uses=1]
    6 ret <4 x i1> %cmp
    7 }
    8
    9 define <4 x i1> @ifoo(<4 x i32> %a, <4 x i32> %b) nounwind {
    10 entry:
    11 %cmp = icmp slt <4 x i32> %a, %b ; <4 x i1> [#uses=1]
    12 ret <4 x i1> %cmp
    13 }
    14
    0 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | grep select
    1 ; rudimentary test of select on vectors returning vector of bool
    2
    3 define <4 x i32> @foo(<4 x i32> %a, <4 x i32> %b,
    4 <4 x i1> %cond) nounwind {
    5 entry:
    6 %cmp = select <4 x i1> %cond, <4 x i32> %a, <4 x i32> %b
    7 ; <4 x i32> [#uses=1]
    8 ret <4 x i32> %cmp
    9 }
    10