Commit 83f9f0c1 by Karl Schimpf

Add icmp and fcmp instructions to Subzero bitcode reader.

parent dd30c81e
...@@ -33,7 +33,8 @@ void __attribute__((unused)) xIceTypeMacroIntegrityCheck() { ...@@ -33,7 +33,8 @@ void __attribute__((unused)) xIceTypeMacroIntegrityCheck() {
}; };
// Define a temporary set of enum values based on ICETYPE_PROPS_TABLE // Define a temporary set of enum values based on ICETYPE_PROPS_TABLE
enum { enum {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) _props_table_tag_##tag, #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, CompareResult) \
_props_table_tag_##tag,
ICETYPE_PROPS_TABLE ICETYPE_PROPS_TABLE
#undef X #undef X
_enum_props_table_tag_Names _enum_props_table_tag_Names
...@@ -44,7 +45,7 @@ void __attribute__((unused)) xIceTypeMacroIntegrityCheck() { ...@@ -44,7 +45,7 @@ void __attribute__((unused)) xIceTypeMacroIntegrityCheck() {
ICETYPE_TABLE; ICETYPE_TABLE;
#undef X #undef X
// Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE. // Assert that tags in ICETYPE_PROPS_TABLE is in ICETYPE_TABLE.
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, CompareResult) \
STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag); STATIC_ASSERT((unsigned)_table_tag_##tag == (unsigned)_props_table_tag_##tag);
ICETYPE_PROPS_TABLE; ICETYPE_PROPS_TABLE;
#undef X #undef X
...@@ -61,13 +62,13 @@ void __attribute__((unused)) xIceTypeMacroIntegrityCheck() { ...@@ -61,13 +62,13 @@ void __attribute__((unused)) xIceTypeMacroIntegrityCheck() {
}; };
// Define constants for boolean flag if vector in ICETYPE_PROPS_TABLE. // Define constants for boolean flag if vector in ICETYPE_PROPS_TABLE.
enum { enum {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, CompareResult) \
_props_table_IsVec_##tag = IsVec, _props_table_IsVec_##tag = IsVec,
ICETYPE_PROPS_TABLE ICETYPE_PROPS_TABLE
#undef X #undef X
}; };
// Verify that the number of vector elements is consistent with IsVec. // Verify that the number of vector elements is consistent with IsVec.
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, CompareResult) \
STATIC_ASSERT((_table_elts_##tag > 1) == _props_table_IsVec_##tag); STATIC_ASSERT((_table_elts_##tag > 1) == _props_table_IsVec_##tag);
ICETYPE_PROPS_TABLE; ICETYPE_PROPS_TABLE;
#undef X #undef X
...@@ -98,13 +99,14 @@ struct TypePropertyFields { ...@@ -98,13 +99,14 @@ struct TypePropertyFields {
bool TypeIsFloatingType; bool TypeIsFloatingType;
bool TypeIsScalarFloatingType; bool TypeIsScalarFloatingType;
bool TypeIsVectorFloatingType; bool TypeIsVectorFloatingType;
Type CompareResultType;
}; };
const TypePropertyFields TypePropertiesTable[] = { const TypePropertyFields TypePropertiesTable[] = {
#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) \ #define X(tag, IsVec, IsInt, IsFloat, IsIntArith, CompareResult) \
{ \ { \
IsVec, IsInt, IsInt && !IsVec, IsInt && IsVec, IsIntArith, IsFloat, \ IsVec, IsInt, IsInt && !IsVec, IsInt && IsVec, IsIntArith, IsFloat, \
IsFloat && !IsVec, IsFloat && IsVec \ IsFloat && !IsVec, IsFloat && IsVec, CompareResult \
} \ } \
, ,
ICETYPE_PROPS_TABLE ICETYPE_PROPS_TABLE
...@@ -209,6 +211,14 @@ bool isVectorFloatingType(Type Ty) { ...@@ -209,6 +211,14 @@ bool isVectorFloatingType(Type Ty) {
return false; return false;
} }
Type getCompareResultType(Type Ty) {
size_t Index = static_cast<size_t>(Ty);
if (Index < IceType_NUM)
return TypePropertiesTable[Index].CompareResultType;
llvm_unreachable("Invalid type for getCompareResultType");
return IceType_void;
}
// ======================== Dump routines ======================== // // ======================== Dump routines ======================== //
const char *typeString(Type Ty) { const char *typeString(Type Ty) {
......
...@@ -40,23 +40,25 @@ ...@@ -40,23 +40,25 @@
// I - Is integer value (scalar or vector). // I - Is integer value (scalar or vector).
// F - Is floating point value (scalar or vector). // F - Is floating point value (scalar or vector).
// IA - Is integer arithmetic type // IA - Is integer arithmetic type
// CR - Result type of compare instruction for argument type
// (IceType_void if disallowed)
#define ICETYPE_PROPS_TABLE \ #define ICETYPE_PROPS_TABLE \
/* Enum Value V I F IA */ \ /* Enum Value V I F IA CR */ \
X(IceType_void, 0, 0, 0, 0) \ X(IceType_void, 0, 0, 0, 0, IceType_void) \
X(IceType_i1, 0, 1, 0, 0) \ X(IceType_i1, 0, 1, 0, 0, IceType_i1) \
X(IceType_i8, 0, 1, 0, 1) \ X(IceType_i8, 0, 1, 0, 1, IceType_i1) \
X(IceType_i16, 0, 1, 0, 1) \ X(IceType_i16, 0, 1, 0, 1, IceType_i1) \
X(IceType_i32, 0, 1, 0, 1) \ X(IceType_i32, 0, 1, 0, 1, IceType_i1) \
X(IceType_i64, 0, 1, 0, 1) \ X(IceType_i64, 0, 1, 0, 1, IceType_i1) \
X(IceType_f32, 0, 0, 1, 0) \ X(IceType_f32, 0, 0, 1, 0, IceType_i1) \
X(IceType_f64, 0, 0, 1, 0) \ X(IceType_f64, 0, 0, 1, 0, IceType_i1) \
X(IceType_v4i1, 1, 1, 0, 0) \ X(IceType_v4i1, 1, 1, 0, 0, IceType_v4i1) \
X(IceType_v8i1, 1, 1, 0, 0) \ X(IceType_v8i1, 1, 1, 0, 0, IceType_v8i1) \
X(IceType_v16i1, 1, 1, 0, 0) \ X(IceType_v16i1, 1, 1, 0, 0, IceType_v16i1) \
X(IceType_v16i8, 1, 1, 0, 1) \ X(IceType_v16i8, 1, 1, 0, 1, IceType_v16i1) \
X(IceType_v8i16, 1, 1, 0, 1) \ X(IceType_v8i16, 1, 1, 0, 1, IceType_v8i1) \
X(IceType_v4i32, 1, 1, 0, 1) \ X(IceType_v4i32, 1, 1, 0, 1, IceType_v4i1) \
X(IceType_v4f32, 1, 0, 1, 0) \ X(IceType_v4f32, 1, 0, 1, 0, IceType_v4i1) \
//#define X(tag, IsVec, IsInt, IsFloat, IsIntArith) //#define X(tag, IsVec, IsInt, IsFloat, IsIntArith, CompareResult)
#endif // SUBZERO_SRC_ICETYPES_DEF #endif // SUBZERO_SRC_ICETYPES_DEF
...@@ -58,6 +58,11 @@ bool isFloatingType(Type Ty); // scalar or vector ...@@ -58,6 +58,11 @@ bool isFloatingType(Type Ty); // scalar or vector
bool isScalarFloatingType(Type Ty); bool isScalarFloatingType(Type Ty);
bool isVectorFloatingType(Type Ty); bool isVectorFloatingType(Type Ty);
/// Returns type generated by applying the compare instructions (icmp and fcmp)
/// to arguments of the given type. Returns IceType_void if compare is not
/// allowed.
Type getCompareResultType(Type Ty);
template <typename StreamType> template <typename StreamType>
inline StreamType &operator<<(StreamType &Str, const Type &Ty) { inline StreamType &operator<<(StreamType &Str, const Type &Ty) {
Str << typeString(Ty); Str << typeString(Ty);
......
...@@ -1034,7 +1034,7 @@ private: ...@@ -1034,7 +1034,7 @@ private:
/// cast opcode and assigns to CastKind. Returns true if successful, /// cast opcode and assigns to CastKind. Returns true if successful,
/// false otherwise. /// false otherwise.
bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp, bool convertLLVMCastOpToIceOp(Instruction::CastOps LLVMCastOp,
Ice::InstCast::OpKind &CastKind) { Ice::InstCast::OpKind &CastKind) const {
switch (LLVMCastOp) { switch (LLVMCastOp) {
case Instruction::ZExt: case Instruction::ZExt:
CastKind = Ice::InstCast::Zext; CastKind = Ice::InstCast::Zext;
...@@ -1071,6 +1071,104 @@ private: ...@@ -1071,6 +1071,104 @@ private:
} }
return true; return true;
} }
// Converts PNaCl bitcode Icmp operator to corresponding ICE op.
// Returns true if able to convert, false otherwise.
bool convertNaClBitcICmpOpToIce(uint64_t Op,
Ice::InstIcmp::ICond &Cond) const {
switch (Op) {
case naclbitc::ICMP_EQ:
Cond = Ice::InstIcmp::Eq;
return true;
case naclbitc::ICMP_NE:
Cond = Ice::InstIcmp::Ne;
return true;
case naclbitc::ICMP_UGT:
Cond = Ice::InstIcmp::Ugt;
return true;
case naclbitc::ICMP_UGE:
Cond = Ice::InstIcmp::Uge;
return true;
case naclbitc::ICMP_ULT:
Cond = Ice::InstIcmp::Ult;
return true;
case naclbitc::ICMP_ULE:
Cond = Ice::InstIcmp::Ule;
return true;
case naclbitc::ICMP_SGT:
Cond = Ice::InstIcmp::Sgt;
return true;
case naclbitc::ICMP_SGE:
Cond = Ice::InstIcmp::Sge;
return true;
case naclbitc::ICMP_SLT:
Cond = Ice::InstIcmp::Slt;
return true;
case naclbitc::ICMP_SLE:
Cond = Ice::InstIcmp::Sle;
return true;
default:
return false;
}
}
// Converts PNaCl bitcode Fcmp operator to corresponding ICE op.
// Returns true if able to convert, false otherwise.
bool convertNaClBitcFCompOpToIce(uint64_t Op,
Ice::InstFcmp::FCond &Cond) const {
switch (Op) {
case naclbitc::FCMP_FALSE:
Cond = Ice::InstFcmp::False;
return true;
case naclbitc::FCMP_OEQ:
Cond = Ice::InstFcmp::Oeq;
return true;
case naclbitc::FCMP_OGT:
Cond = Ice::InstFcmp::Ogt;
return true;
case naclbitc::FCMP_OGE:
Cond = Ice::InstFcmp::Oge;
return true;
case naclbitc::FCMP_OLT:
Cond = Ice::InstFcmp::Olt;
return true;
case naclbitc::FCMP_OLE:
Cond = Ice::InstFcmp::Ole;
return true;
case naclbitc::FCMP_ONE:
Cond = Ice::InstFcmp::One;
return true;
case naclbitc::FCMP_ORD:
Cond = Ice::InstFcmp::Ord;
return true;
case naclbitc::FCMP_UNO:
Cond = Ice::InstFcmp::Uno;
return true;
case naclbitc::FCMP_UEQ:
Cond = Ice::InstFcmp::Ueq;
return true;
case naclbitc::FCMP_UGT:
Cond = Ice::InstFcmp::Ugt;
return true;
case naclbitc::FCMP_UGE:
Cond = Ice::InstFcmp::Uge;
return true;
case naclbitc::FCMP_ULT:
Cond = Ice::InstFcmp::Ult;
return true;
case naclbitc::FCMP_ULE:
Cond = Ice::InstFcmp::Ule;
return true;
case naclbitc::FCMP_UNE:
Cond = Ice::InstFcmp::Une;
return true;
case naclbitc::FCMP_TRUE:
Cond = Ice::InstFcmp::True;
return true;
default:
return false;
}
}
}; };
FunctionParser::~FunctionParser() { FunctionParser::~FunctionParser() {
...@@ -1238,6 +1336,8 @@ void FunctionParser::ProcessRecord() { ...@@ -1238,6 +1336,8 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_EXTRACTELT: { case naclbitc::FUNC_CODE_INST_EXTRACTELT: {
// EXTRACTELT: [opval, opval] // EXTRACTELT: [opval, opval]
if (!isValidRecordSize(2, "function block extract element"))
return;
Ice::Operand *Vec = getRelativeOperand(Values[0]); Ice::Operand *Vec = getRelativeOperand(Values[0]);
Ice::Type VecType = Vec->getType(); Ice::Type VecType = Vec->getType();
if (!Ice::isVectorType(VecType)) { if (!Ice::isVectorType(VecType)) {
...@@ -1261,6 +1361,8 @@ void FunctionParser::ProcessRecord() { ...@@ -1261,6 +1361,8 @@ void FunctionParser::ProcessRecord() {
} }
case naclbitc::FUNC_CODE_INST_INSERTELT: { case naclbitc::FUNC_CODE_INST_INSERTELT: {
// INSERTELT: [opval, opval, opval] // INSERTELT: [opval, opval, opval]
if (!isValidRecordSize(3, "function block insert element"))
return;
Ice::Operand *Vec = getRelativeOperand(Values[0]); Ice::Operand *Vec = getRelativeOperand(Values[0]);
Ice::Type VecType = Vec->getType(); Ice::Type VecType = Vec->getType();
if (!Ice::isVectorType(VecType)) { if (!Ice::isVectorType(VecType)) {
...@@ -1291,6 +1393,66 @@ void FunctionParser::ProcessRecord() { ...@@ -1291,6 +1393,66 @@ void FunctionParser::ProcessRecord() {
Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index); Inst = Ice::InstInsertElement::create(Func, Dest, Vec, Elt, Index);
break; break;
} }
case naclbitc::FUNC_CODE_INST_CMP2: {
// CMP2: [opval, opval, pred]
if (!isValidRecordSize(3, "function block compare"))
return;
Ice::Operand *Op1 = getRelativeOperand(Values[0]);
Ice::Operand *Op2 = getRelativeOperand(Values[1]);
Ice::Type Op1Type = Op1->getType();
Ice::Type Op2Type = Op2->getType();
if (Op1Type != Op2Type) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Compare argument types differ: " << Op1Type
<< " and " << Op2Type;
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Op2 = Op1;
}
Ice::Type DestType = getCompareResultType(Op1Type);
if (DestType == Ice::IceType_void) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Compare not defined for type " << Op1Type;
Error(StrBuf.str());
return;
}
Ice::Variable *Dest = NextInstVar(DestType);
if (isIntegerType(Op1Type)) {
Ice::InstIcmp::ICond Cond;
if (!convertNaClBitcICmpOpToIce(Values[2], Cond)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Compare record contains unknown integer predicate index: "
<< Values[2];
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Cond = Ice::InstIcmp::Eq;
}
Inst = Ice::InstIcmp::create(Func, Cond, Dest, Op1, Op2);
} else if (isFloatingType(Op1Type)){
Ice::InstFcmp::FCond Cond;
if (!convertNaClBitcFCompOpToIce(Values[2], Cond)) {
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Compare record contains unknown float predicate index: "
<< Values[2];
Error(StrBuf.str());
// TODO(kschimpf) Remove error recovery once implementation complete.
Cond = Ice::InstFcmp::False;
}
Inst = Ice::InstFcmp::create(Func, Cond, Dest, Op1, Op2);
} else {
// Not sure this can happen, but be safe.
std::string Buffer;
raw_string_ostream StrBuf(Buffer);
StrBuf << "Compare on type not understood: " << Op1Type;
Error(StrBuf.str());
return;
}
break;
}
case naclbitc::FUNC_CODE_INST_RET: { case naclbitc::FUNC_CODE_INST_RET: {
// RET: [opval?] // RET: [opval?]
InstIsTerminating = true; InstIsTerminating = true;
......
; Test if we can read compare instructions.
; RUN: llvm-as < %s | pnacl-freeze \
; RUN: | %llvm2ice -notranslate -verbose=inst -build-on-read \
; RUN: -allow-pnacl-reader-error-recovery \
; RUN: | FileCheck %s
define i1 @IcmpI1(i32 %p1, i32 %p2) {
%a1 = trunc i32 %p1 to i1
%a2 = trunc i32 %p2 to i1
%veq = icmp eq i1 %a1, %a2
%vne = icmp ne i1 %a1, %a2
%vugt = icmp ugt i1 %a1, %a2
%vuge = icmp uge i1 %a1, %a2
%vult = icmp ult i1 %a1, %a2
%vule = icmp ule i1 %a1, %a2
%vsgt = icmp sgt i1 %a1, %a2
%vsge = icmp sge i1 %a1, %a2
%vslt = icmp slt i1 %a1, %a2
%vsle = icmp sle i1 %a1, %a2
ret i1 %veq
}
; CHECK: define i1 @IcmpI1(i32 %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = trunc i32 %__0 to i1
; CHECK-NEXT: %__3 = trunc i32 %__1 to i1
; CHECK-NEXT: %__4 = icmp eq i1 %__2, %__3
; CHECK-NEXT: %__5 = icmp ne i1 %__2, %__3
; CHECK-NEXT: %__6 = icmp ugt i1 %__2, %__3
; CHECK-NEXT: %__7 = icmp uge i1 %__2, %__3
; CHECK-NEXT: %__8 = icmp ult i1 %__2, %__3
; CHECK-NEXT: %__9 = icmp ule i1 %__2, %__3
; CHECK-NEXT: %__10 = icmp sgt i1 %__2, %__3
; CHECK-NEXT: %__11 = icmp sge i1 %__2, %__3
; CHECK-NEXT: %__12 = icmp slt i1 %__2, %__3
; CHECK-NEXT: %__13 = icmp sle i1 %__2, %__3
; CHECK-NEXT: ret i1 %__4
; CHECK-NEXT: }
define i1 @IcmpI8(i32 %p1, i32 %p2) {
%a1 = trunc i32 %p1 to i8
%a2 = trunc i32 %p2 to i8
%veq = icmp eq i8 %a1, %a2
%vne = icmp ne i8 %a1, %a2
%vugt = icmp ugt i8 %a1, %a2
%vuge = icmp uge i8 %a1, %a2
%vult = icmp ult i8 %a1, %a2
%vule = icmp ule i8 %a1, %a2
%vsgt = icmp sgt i8 %a1, %a2
%vsge = icmp sge i8 %a1, %a2
%vslt = icmp slt i8 %a1, %a2
%vsle = icmp sle i8 %a1, %a2
ret i1 %veq
}
; CHECK-NEXT: define i1 @IcmpI8(i32 %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = trunc i32 %__0 to i8
; CHECK-NEXT: %__3 = trunc i32 %__1 to i8
; CHECK-NEXT: %__4 = icmp eq i8 %__2, %__3
; CHECK-NEXT: %__5 = icmp ne i8 %__2, %__3
; CHECK-NEXT: %__6 = icmp ugt i8 %__2, %__3
; CHECK-NEXT: %__7 = icmp uge i8 %__2, %__3
; CHECK-NEXT: %__8 = icmp ult i8 %__2, %__3
; CHECK-NEXT: %__9 = icmp ule i8 %__2, %__3
; CHECK-NEXT: %__10 = icmp sgt i8 %__2, %__3
; CHECK-NEXT: %__11 = icmp sge i8 %__2, %__3
; CHECK-NEXT: %__12 = icmp slt i8 %__2, %__3
; CHECK-NEXT: %__13 = icmp sle i8 %__2, %__3
; CHECK-NEXT: ret i1 %__4
; CHECK-NEXT: }
define i1 @IcmpI16(i32 %p1, i32 %p2) {
%a1 = trunc i32 %p1 to i16
%a2 = trunc i32 %p2 to i16
%veq = icmp eq i16 %a1, %a2
%vne = icmp ne i16 %a1, %a2
%vugt = icmp ugt i16 %a1, %a2
%vuge = icmp uge i16 %a1, %a2
%vult = icmp ult i16 %a1, %a2
%vule = icmp ule i16 %a1, %a2
%vsgt = icmp sgt i16 %a1, %a2
%vsge = icmp sge i16 %a1, %a2
%vslt = icmp slt i16 %a1, %a2
%vsle = icmp sle i16 %a1, %a2
ret i1 %veq
}
; CHECK-NEXT: define i1 @IcmpI16(i32 %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = trunc i32 %__0 to i16
; CHECK-NEXT: %__3 = trunc i32 %__1 to i16
; CHECK-NEXT: %__4 = icmp eq i16 %__2, %__3
; CHECK-NEXT: %__5 = icmp ne i16 %__2, %__3
; CHECK-NEXT: %__6 = icmp ugt i16 %__2, %__3
; CHECK-NEXT: %__7 = icmp uge i16 %__2, %__3
; CHECK-NEXT: %__8 = icmp ult i16 %__2, %__3
; CHECK-NEXT: %__9 = icmp ule i16 %__2, %__3
; CHECK-NEXT: %__10 = icmp sgt i16 %__2, %__3
; CHECK-NEXT: %__11 = icmp sge i16 %__2, %__3
; CHECK-NEXT: %__12 = icmp slt i16 %__2, %__3
; CHECK-NEXT: %__13 = icmp sle i16 %__2, %__3
; CHECK-NEXT: ret i1 %__4
; CHECK-NEXT: }
define i1 @IcmpI32(i32 %a1, i32 %a2) {
%veq = icmp eq i32 %a1, %a2
%vne = icmp ne i32 %a1, %a2
%vugt = icmp ugt i32 %a1, %a2
%vuge = icmp uge i32 %a1, %a2
%vult = icmp ult i32 %a1, %a2
%vule = icmp ule i32 %a1, %a2
%vsgt = icmp sgt i32 %a1, %a2
%vsge = icmp sge i32 %a1, %a2
%vslt = icmp slt i32 %a1, %a2
%vsle = icmp sle i32 %a1, %a2
ret i1 %veq
}
; CHECK-NEXT: define i1 @IcmpI32(i32 %__0, i32 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq i32 %__0, %__1
; CHECK-NEXT: %__3 = icmp ne i32 %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt i32 %__0, %__1
; CHECK-NEXT: %__5 = icmp uge i32 %__0, %__1
; CHECK-NEXT: %__6 = icmp ult i32 %__0, %__1
; CHECK-NEXT: %__7 = icmp ule i32 %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt i32 %__0, %__1
; CHECK-NEXT: %__9 = icmp sge i32 %__0, %__1
; CHECK-NEXT: %__10 = icmp slt i32 %__0, %__1
; CHECK-NEXT: %__11 = icmp sle i32 %__0, %__1
; CHECK-NEXT: ret i1 %__2
; CHECK-NEXT: }
define i1 @IcmpI64(i64 %a1, i64 %a2) {
%veq = icmp eq i64 %a1, %a2
%vne = icmp ne i64 %a1, %a2
%vugt = icmp ugt i64 %a1, %a2
%vuge = icmp uge i64 %a1, %a2
%vult = icmp ult i64 %a1, %a2
%vule = icmp ule i64 %a1, %a2
%vsgt = icmp sgt i64 %a1, %a2
%vsge = icmp sge i64 %a1, %a2
%vslt = icmp slt i64 %a1, %a2
%vsle = icmp sle i64 %a1, %a2
ret i1 %veq
}
; CHECK-NEXT: define i1 @IcmpI64(i64 %__0, i64 %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq i64 %__0, %__1
; CHECK-NEXT: %__3 = icmp ne i64 %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt i64 %__0, %__1
; CHECK-NEXT: %__5 = icmp uge i64 %__0, %__1
; CHECK-NEXT: %__6 = icmp ult i64 %__0, %__1
; CHECK-NEXT: %__7 = icmp ule i64 %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt i64 %__0, %__1
; CHECK-NEXT: %__9 = icmp sge i64 %__0, %__1
; CHECK-NEXT: %__10 = icmp slt i64 %__0, %__1
; CHECK-NEXT: %__11 = icmp sle i64 %__0, %__1
; CHECK-NEXT: ret i1 %__2
; CHECK-NEXT: }
define <4 x i1> @IcmpV4xI1(<4 x i1> %a1, <4 x i1> %a2) {
%veq = icmp eq <4 x i1> %a1, %a2
%vne = icmp ne <4 x i1> %a1, %a2
%vugt = icmp ugt <4 x i1> %a1, %a2
%vuge = icmp uge <4 x i1> %a1, %a2
%vult = icmp ult <4 x i1> %a1, %a2
%vule = icmp ule <4 x i1> %a1, %a2
%vsgt = icmp sgt <4 x i1> %a1, %a2
%vsge = icmp sge <4 x i1> %a1, %a2
%vslt = icmp slt <4 x i1> %a1, %a2
%vsle = icmp sle <4 x i1> %a1, %a2
ret <4 x i1> %veq
}
; CHECK-NEXT: define <4 x i1> @IcmpV4xI1(<4 x i1> %__0, <4 x i1> %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq <4 x i1> %__0, %__1
; CHECK-NEXT: %__3 = icmp ne <4 x i1> %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt <4 x i1> %__0, %__1
; CHECK-NEXT: %__5 = icmp uge <4 x i1> %__0, %__1
; CHECK-NEXT: %__6 = icmp ult <4 x i1> %__0, %__1
; CHECK-NEXT: %__7 = icmp ule <4 x i1> %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt <4 x i1> %__0, %__1
; CHECK-NEXT: %__9 = icmp sge <4 x i1> %__0, %__1
; CHECK-NEXT: %__10 = icmp slt <4 x i1> %__0, %__1
; CHECK-NEXT: %__11 = icmp sle <4 x i1> %__0, %__1
; CHECK-NEXT: ret <4 x i1> %__2
; CHECK-NEXT: }
define <8 x i1> @IcmpV8xI1(<8 x i1> %a1, <8 x i1> %a2) {
%veq = icmp eq <8 x i1> %a1, %a2
%vne = icmp ne <8 x i1> %a1, %a2
%vugt = icmp ugt <8 x i1> %a1, %a2
%vuge = icmp uge <8 x i1> %a1, %a2
%vult = icmp ult <8 x i1> %a1, %a2
%vule = icmp ule <8 x i1> %a1, %a2
%vsgt = icmp sgt <8 x i1> %a1, %a2
%vsge = icmp sge <8 x i1> %a1, %a2
%vslt = icmp slt <8 x i1> %a1, %a2
%vsle = icmp sle <8 x i1> %a1, %a2
ret <8 x i1> %veq
}
; CHECK-NEXT: define <8 x i1> @IcmpV8xI1(<8 x i1> %__0, <8 x i1> %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq <8 x i1> %__0, %__1
; CHECK-NEXT: %__3 = icmp ne <8 x i1> %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt <8 x i1> %__0, %__1
; CHECK-NEXT: %__5 = icmp uge <8 x i1> %__0, %__1
; CHECK-NEXT: %__6 = icmp ult <8 x i1> %__0, %__1
; CHECK-NEXT: %__7 = icmp ule <8 x i1> %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt <8 x i1> %__0, %__1
; CHECK-NEXT: %__9 = icmp sge <8 x i1> %__0, %__1
; CHECK-NEXT: %__10 = icmp slt <8 x i1> %__0, %__1
; CHECK-NEXT: %__11 = icmp sle <8 x i1> %__0, %__1
; CHECK-NEXT: ret <8 x i1> %__2
; CHECK-NEXT: }
define <16 x i1> @IcmpV16xI1(<16 x i1> %a1, <16 x i1> %a2) {
%veq = icmp eq <16 x i1> %a1, %a2
%vne = icmp ne <16 x i1> %a1, %a2
%vugt = icmp ugt <16 x i1> %a1, %a2
%vuge = icmp uge <16 x i1> %a1, %a2
%vult = icmp ult <16 x i1> %a1, %a2
%vule = icmp ule <16 x i1> %a1, %a2
%vsgt = icmp sgt <16 x i1> %a1, %a2
%vsge = icmp sge <16 x i1> %a1, %a2
%vslt = icmp slt <16 x i1> %a1, %a2
%vsle = icmp sle <16 x i1> %a1, %a2
ret <16 x i1> %veq
}
; CHECK-NEXT: define <16 x i1> @IcmpV16xI1(<16 x i1> %__0, <16 x i1> %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq <16 x i1> %__0, %__1
; CHECK-NEXT: %__3 = icmp ne <16 x i1> %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt <16 x i1> %__0, %__1
; CHECK-NEXT: %__5 = icmp uge <16 x i1> %__0, %__1
; CHECK-NEXT: %__6 = icmp ult <16 x i1> %__0, %__1
; CHECK-NEXT: %__7 = icmp ule <16 x i1> %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt <16 x i1> %__0, %__1
; CHECK-NEXT: %__9 = icmp sge <16 x i1> %__0, %__1
; CHECK-NEXT: %__10 = icmp slt <16 x i1> %__0, %__1
; CHECK-NEXT: %__11 = icmp sle <16 x i1> %__0, %__1
; CHECK-NEXT: ret <16 x i1> %__2
; CHECK-NEXT: }
define <16 x i1> @IcmpV16xI8(<16 x i8> %a1, <16 x i8> %a2) {
%veq = icmp eq <16 x i8> %a1, %a2
%vne = icmp ne <16 x i8> %a1, %a2
%vugt = icmp ugt <16 x i8> %a1, %a2
%vuge = icmp uge <16 x i8> %a1, %a2
%vult = icmp ult <16 x i8> %a1, %a2
%vule = icmp ule <16 x i8> %a1, %a2
%vsgt = icmp sgt <16 x i8> %a1, %a2
%vsge = icmp sge <16 x i8> %a1, %a2
%vslt = icmp slt <16 x i8> %a1, %a2
%vsle = icmp sle <16 x i8> %a1, %a2
ret <16 x i1> %veq
}
; CHECK-NEXT: define <16 x i1> @IcmpV16xI8(<16 x i8> %__0, <16 x i8> %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq <16 x i8> %__0, %__1
; CHECK-NEXT: %__3 = icmp ne <16 x i8> %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt <16 x i8> %__0, %__1
; CHECK-NEXT: %__5 = icmp uge <16 x i8> %__0, %__1
; CHECK-NEXT: %__6 = icmp ult <16 x i8> %__0, %__1
; CHECK-NEXT: %__7 = icmp ule <16 x i8> %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt <16 x i8> %__0, %__1
; CHECK-NEXT: %__9 = icmp sge <16 x i8> %__0, %__1
; CHECK-NEXT: %__10 = icmp slt <16 x i8> %__0, %__1
; CHECK-NEXT: %__11 = icmp sle <16 x i8> %__0, %__1
; CHECK-NEXT: ret <16 x i1> %__2
; CHECK-NEXT: }
define <8 x i1> @IcmpV8xI16(<8 x i16> %a1, <8 x i16> %a2) {
%veq = icmp eq <8 x i16> %a1, %a2
%vne = icmp ne <8 x i16> %a1, %a2
%vugt = icmp ugt <8 x i16> %a1, %a2
%vuge = icmp uge <8 x i16> %a1, %a2
%vult = icmp ult <8 x i16> %a1, %a2
%vule = icmp ule <8 x i16> %a1, %a2
%vsgt = icmp sgt <8 x i16> %a1, %a2
%vsge = icmp sge <8 x i16> %a1, %a2
%vslt = icmp slt <8 x i16> %a1, %a2
%vsle = icmp sle <8 x i16> %a1, %a2
ret <8 x i1> %veq
}
; CHECK-NEXT: define <8 x i1> @IcmpV8xI16(<8 x i16> %__0, <8 x i16> %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq <8 x i16> %__0, %__1
; CHECK-NEXT: %__3 = icmp ne <8 x i16> %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt <8 x i16> %__0, %__1
; CHECK-NEXT: %__5 = icmp uge <8 x i16> %__0, %__1
; CHECK-NEXT: %__6 = icmp ult <8 x i16> %__0, %__1
; CHECK-NEXT: %__7 = icmp ule <8 x i16> %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt <8 x i16> %__0, %__1
; CHECK-NEXT: %__9 = icmp sge <8 x i16> %__0, %__1
; CHECK-NEXT: %__10 = icmp slt <8 x i16> %__0, %__1
; CHECK-NEXT: %__11 = icmp sle <8 x i16> %__0, %__1
; CHECK-NEXT: ret <8 x i1> %__2
; CHECK-NEXT: }
define <4 x i1> @IcmpV4xI32(<4 x i32> %a1, <4 x i32> %a2) {
%veq = icmp eq <4 x i32> %a1, %a2
%vne = icmp ne <4 x i32> %a1, %a2
%vugt = icmp ugt <4 x i32> %a1, %a2
%vuge = icmp uge <4 x i32> %a1, %a2
%vult = icmp ult <4 x i32> %a1, %a2
%vule = icmp ule <4 x i32> %a1, %a2
%vsgt = icmp sgt <4 x i32> %a1, %a2
%vsge = icmp sge <4 x i32> %a1, %a2
%vslt = icmp slt <4 x i32> %a1, %a2
%vsle = icmp sle <4 x i32> %a1, %a2
ret <4 x i1> %veq
}
; CHECK-NEXT: define <4 x i1> @IcmpV4xI32(<4 x i32> %__0, <4 x i32> %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = icmp eq <4 x i32> %__0, %__1
; CHECK-NEXT: %__3 = icmp ne <4 x i32> %__0, %__1
; CHECK-NEXT: %__4 = icmp ugt <4 x i32> %__0, %__1
; CHECK-NEXT: %__5 = icmp uge <4 x i32> %__0, %__1
; CHECK-NEXT: %__6 = icmp ult <4 x i32> %__0, %__1
; CHECK-NEXT: %__7 = icmp ule <4 x i32> %__0, %__1
; CHECK-NEXT: %__8 = icmp sgt <4 x i32> %__0, %__1
; CHECK-NEXT: %__9 = icmp sge <4 x i32> %__0, %__1
; CHECK-NEXT: %__10 = icmp slt <4 x i32> %__0, %__1
; CHECK-NEXT: %__11 = icmp sle <4 x i32> %__0, %__1
; CHECK-NEXT: ret <4 x i1> %__2
; CHECK-NEXT: }
define i1 @FcmpFloat(float %a1, float %a2) {
%vfalse = fcmp false float %a1, %a2
%voeq = fcmp oeq float %a1, %a2
%vogt = fcmp ogt float %a1, %a2
%voge = fcmp oge float %a1, %a2
%volt = fcmp olt float %a1, %a2
%vole = fcmp ole float %a1, %a2
%vone = fcmp one float %a1, %a2
%ord = fcmp ord float %a1, %a2
%vueq = fcmp ueq float %a1, %a2
%vugt = fcmp ugt float %a1, %a2
%vuge = fcmp uge float %a1, %a2
%vult = fcmp ult float %a1, %a2
%vule = fcmp ule float %a1, %a2
%vune = fcmp une float %a1, %a2
%vuno = fcmp uno float %a1, %a2
%vtrue = fcmp true float %a1, %a2
ret i1 %voeq
}
; CHECK-NEXT: define i1 @FcmpFloat(float %__0, float %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = fcmp false float %__0, %__1
; CHECK-NEXT: %__3 = fcmp oeq float %__0, %__1
; CHECK-NEXT: %__4 = fcmp ogt float %__0, %__1
; CHECK-NEXT: %__5 = fcmp oge float %__0, %__1
; CHECK-NEXT: %__6 = fcmp olt float %__0, %__1
; CHECK-NEXT: %__7 = fcmp ole float %__0, %__1
; CHECK-NEXT: %__8 = fcmp one float %__0, %__1
; CHECK-NEXT: %__9 = fcmp ord float %__0, %__1
; CHECK-NEXT: %__10 = fcmp ueq float %__0, %__1
; CHECK-NEXT: %__11 = fcmp ugt float %__0, %__1
; CHECK-NEXT: %__12 = fcmp uge float %__0, %__1
; CHECK-NEXT: %__13 = fcmp ult float %__0, %__1
; CHECK-NEXT: %__14 = fcmp ule float %__0, %__1
; CHECK-NEXT: %__15 = fcmp une float %__0, %__1
; CHECK-NEXT: %__16 = fcmp uno float %__0, %__1
; CHECK-NEXT: %__17 = fcmp true float %__0, %__1
; CHECK-NEXT: ret i1 %__3
; CHECK-NEXT: }
define i1 @FcmpDouble(double %a1, double %a2) {
%vfalse = fcmp false double %a1, %a2
%voeq = fcmp oeq double %a1, %a2
%vogt = fcmp ogt double %a1, %a2
%voge = fcmp oge double %a1, %a2
%volt = fcmp olt double %a1, %a2
%vole = fcmp ole double %a1, %a2
%vone = fcmp one double %a1, %a2
%ord = fcmp ord double %a1, %a2
%vueq = fcmp ueq double %a1, %a2
%vugt = fcmp ugt double %a1, %a2
%vuge = fcmp uge double %a1, %a2
%vult = fcmp ult double %a1, %a2
%vule = fcmp ule double %a1, %a2
%vune = fcmp une double %a1, %a2
%vuno = fcmp uno double %a1, %a2
%vtrue = fcmp true double %a1, %a2
ret i1 %voeq
}
; CHECK-NEXT: define i1 @FcmpDouble(double %__0, double %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = fcmp false double %__0, %__1
; CHECK-NEXT: %__3 = fcmp oeq double %__0, %__1
; CHECK-NEXT: %__4 = fcmp ogt double %__0, %__1
; CHECK-NEXT: %__5 = fcmp oge double %__0, %__1
; CHECK-NEXT: %__6 = fcmp olt double %__0, %__1
; CHECK-NEXT: %__7 = fcmp ole double %__0, %__1
; CHECK-NEXT: %__8 = fcmp one double %__0, %__1
; CHECK-NEXT: %__9 = fcmp ord double %__0, %__1
; CHECK-NEXT: %__10 = fcmp ueq double %__0, %__1
; CHECK-NEXT: %__11 = fcmp ugt double %__0, %__1
; CHECK-NEXT: %__12 = fcmp uge double %__0, %__1
; CHECK-NEXT: %__13 = fcmp ult double %__0, %__1
; CHECK-NEXT: %__14 = fcmp ule double %__0, %__1
; CHECK-NEXT: %__15 = fcmp une double %__0, %__1
; CHECK-NEXT: %__16 = fcmp uno double %__0, %__1
; CHECK-NEXT: %__17 = fcmp true double %__0, %__1
; CHECK-NEXT: ret i1 %__3
; CHECK-NEXT: }
define <4 x i1> @FcmpV4xFloat(<4 x float> %a1, <4 x float> %a2) {
%vfalse = fcmp false <4 x float> %a1, %a2
%voeq = fcmp oeq <4 x float> %a1, %a2
%vogt = fcmp ogt <4 x float> %a1, %a2
%voge = fcmp oge <4 x float> %a1, %a2
%volt = fcmp olt <4 x float> %a1, %a2
%vole = fcmp ole <4 x float> %a1, %a2
%vone = fcmp one <4 x float> %a1, %a2
%ord = fcmp ord <4 x float> %a1, %a2
%vueq = fcmp ueq <4 x float> %a1, %a2
%vugt = fcmp ugt <4 x float> %a1, %a2
%vuge = fcmp uge <4 x float> %a1, %a2
%vult = fcmp ult <4 x float> %a1, %a2
%vule = fcmp ule <4 x float> %a1, %a2
%vune = fcmp une <4 x float> %a1, %a2
%vuno = fcmp uno <4 x float> %a1, %a2
%vtrue = fcmp true <4 x float> %a1, %a2
ret <4 x i1> %voeq
}
; CHECK-NEXT: define <4 x i1> @FcmpV4xFloat(<4 x float> %__0, <4 x float> %__1) {
; CHECK-NEXT: __0:
; CHECK-NEXT: %__2 = fcmp false <4 x float> %__0, %__1
; CHECK-NEXT: %__3 = fcmp oeq <4 x float> %__0, %__1
; CHECK-NEXT: %__4 = fcmp ogt <4 x float> %__0, %__1
; CHECK-NEXT: %__5 = fcmp oge <4 x float> %__0, %__1
; CHECK-NEXT: %__6 = fcmp olt <4 x float> %__0, %__1
; CHECK-NEXT: %__7 = fcmp ole <4 x float> %__0, %__1
; CHECK-NEXT: %__8 = fcmp one <4 x float> %__0, %__1
; CHECK-NEXT: %__9 = fcmp ord <4 x float> %__0, %__1
; CHECK-NEXT: %__10 = fcmp ueq <4 x float> %__0, %__1
; CHECK-NEXT: %__11 = fcmp ugt <4 x float> %__0, %__1
; CHECK-NEXT: %__12 = fcmp uge <4 x float> %__0, %__1
; CHECK-NEXT: %__13 = fcmp ult <4 x float> %__0, %__1
; CHECK-NEXT: %__14 = fcmp ule <4 x float> %__0, %__1
; CHECK-NEXT: %__15 = fcmp une <4 x float> %__0, %__1
; CHECK-NEXT: %__16 = fcmp uno <4 x float> %__0, %__1
; CHECK-NEXT: %__17 = fcmp true <4 x float> %__0, %__1
; CHECK-NEXT: ret <4 x i1> %__3
; CHECK-NEXT: }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment