// NewICmp returns a new icmp instruction based on the given condition and // operands. // // Pre-condition: x and y are of identical types. x and y are of integer, // integer vector, pointer or pointer vector type. func NewICmp(cond ICond, x, y value.Value) (*ICmp, error) { // Validate that x and y are of identical types. if !types.Equal(x.Type(), y.Type()) { return nil, errutil.Newf("type mismatch between x (%v) and y (%v)", x.Type(), y.Type()) } // Validate that x and y are of integer, integer vector, pointer or pointer // vector type. if !types.IsInts(x.Type()) && !types.IsPointers(x.Type()) { return nil, errutil.Newf("invalid x operand type; expected integer, integer vector, pointer or pointer vector, got %v", x.Type()) } if !types.IsInts(y.Type()) && !types.IsPointers(y.Type()) { return nil, errutil.Newf("invalid y operand type; expected integer, integer vector, pointer or pointer vector, got %v", y.Type()) } return &ICmp{cond: cond, x: x, y: y}, nil }
func TestIsInts(t *testing.T) { golden := []struct { want bool typ types.Type }{ {want: false, typ: voidTyp}, // void {want: true, typ: i1Typ}, // i1 {want: true, typ: i8Typ}, // i8 {want: true, typ: i32Typ}, // i32 {want: false, typ: f16Typ}, // half {want: false, typ: f32Typ}, // float {want: false, typ: f64Typ}, // double {want: false, typ: f128Typ}, // fp128 {want: false, typ: f80_x86Typ}, // x86_fp80 {want: false, typ: f128_ppcTyp}, // ppc_fp128 {want: false, typ: mmxTyp}, // x86_mmx {want: false, typ: labelTyp}, // label {want: false, typ: metadataTyp}, // metadata {want: false, typ: funcTyp}, // i32 (i32) {want: false, typ: i8PtrTyp}, // i8* {want: false, typ: f16PtrTyp}, // half* {want: false, typ: mmxPtrTyp}, // x86_mmx* {want: false, typ: funcPtrTyp}, // i32 (i32)* {want: true, typ: i8x1VecTyp}, //<[1 x i8> {want: true, typ: i32x2VecTyp}, //<[2 x i32> {want: false, typ: f16x3VecTyp}, //<[3 x half> {want: false, typ: f32x4VecTyp}, //<[4 x float> {want: false, typ: f64x5VecTyp}, //<[5 x double> {want: false, typ: f128x6VecTyp}, //<[6 x fp128> {want: false, typ: f80_x86x7VecTyp}, //<[7 x x86_fp80> {want: false, typ: f128_ppcx8VecTyp}, //<[8 x ppc_fp128> {want: false, typ: i8Ptrx9VecTyp}, //<[9 x i8*> {want: false, typ: f16Ptrx10VecTyp}, //<[10 x half*> {want: false, typ: i8x1ArrTyp}, // [1 x i8] {want: false, typ: i32x2ArrTyp}, // [2 x i32] {want: false, typ: f16x3ArrTyp}, // [3 x half] {want: false, typ: f32x4ArrTyp}, // [4 x float] {want: false, typ: f64x5ArrTyp}, // [5 x double] {want: false, typ: f128x6ArrTyp}, // [6 x fp128] {want: false, typ: f80_x86x7ArrTyp}, // [7 x x86_fp80] {want: false, typ: f128_ppcx8ArrTyp}, // [8 x ppc_fp128] {want: false, typ: i8Ptrx9ArrTyp}, // [9 x i8*] {want: false, typ: f16Ptrx10ArrTyp}, // [10 x half*] {want: false, typ: structTyp}, // {i1, float, x86_mmx, i32 (i32)*, [1 x i8], <3 x half>} } for i, g := range golden { got := types.IsInts(g.typ) if got != g.want { t.Errorf("i=%d: expected %v, got %v for type %q", i, g.want, got, g.typ) } } }
// NewSIToFP returns a constant expression which converts the signed integer // constant (or constant vector) orig to the corresponding floating point // constant (or constant vector). func NewSIToFP(orig Constant, to types.Type) (*SIToFP, error) { // Verify type of original integer constant (or constant vector). if !types.IsInts(orig.Type()) { return nil, fmt.Errorf("invalid signed integer to floating point conversion; expected integer constant (or constant vector) for orig, got %q", orig.Type()) } // Verify target type. if !types.IsFloats(to) { return nil, fmt.Errorf("invalid signed integer to floating point conversion; expected floating point (or floating point vector) target type, got %q", to) } // Verify that both are either basic types or vectors of the same length. if !types.SameLength(orig.Type(), to) { return nil, fmt.Errorf("invalid signed integer to floating point conversion; cannot convert from %q to %q", orig.Type(), to) } return &SIToFP{orig: orig, to: to}, nil }