contract U256BasicTest { fn testU256DeclareUninitialized() { u256 a; print(a); } // BEGIN-CHECK: define void @testU256DeclareInitialized() fn testU256DeclareInitialized() { // CHECK: %a = alloca i64, align 8 // CHECK: store i64 5, ptr %a, align 4 u256 a = 5; print(a); } // BEGIN-CHECK: define void @testU256DeclareThenInitialized() fn testU256DeclareThenInitialized() { // CHECK: %a = alloca i64, align 8 // CHECK: store i64 0, ptr %a, align 4 u256 a; // CHECK: store i64 5, ptr %a, align 4 a = 5; print(a); } // BEGIN-CHECK: define void @testU256InitializedByOther() fn testU256InitializedByOther() { // CHECK: %b = alloca i64, align 8 // CHECK: %a = alloca i64, align 8 // CHECK: store i64 5, ptr %a, align 4 u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: store i64 %0, ptr %b, align 4 u256 b = a; print(b); } // BEGIN-CHECK: define void @testU256LeftValueExpression() fn testU256LeftValueExpression() { // CHECK: %a = alloca i64, align 8 // CHECK: store i64 5, ptr %a, align 4 u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: store i64 %0, ptr %a, align 4 a = a; print(a); } // BEGIN-CHECK: define void @testU256RightValueExpression() fn testU256RightValueExpression() { // CHECK: %b = alloca i64, align 8 // CHECK: %a = alloca i64, align 8 // CHECK: store i64 5, ptr %a, align 4 u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %a, align 4 // CHECK: %2 = add i64 %0, %1 // CHECK: store i64 %2, ptr %b, align 4 u256 b = a + a; print(b); } // BEGIN-CHECK: define void @testU256AsParameter(i64 %0) fn testU256AsParameter(u256 x) { // CHECK: %x = alloca i64, align 8 // CHECK: store i64 %0, ptr %x, align 4 print(x); } // BEGIN-CHECK: define void @testU256CallByValue() fn testU256CallByValue() { // CHECK: %a = alloca i64, align 8 // CHECK: store i64 5, ptr %a, align 4 u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: call void @testU256AsParameter(i64 %0) testU256AsParameter(a); } // BEGIN-CHECK: define i64 @testU256AsReturnValue() fn testU256AsReturnValue() -> (u256) { // CHECK: %a = alloca i64, align 8 // CHECK: store i64 10, ptr %a, align 4 u256 a = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: ret i64 %0 return a; } // BEGIN-CHECK: define i64 @testU256AsReturnConstValue() fn testU256AsReturnConstValue() -> (u256) { // CHECK: ret i64 5 return 5; } // BEGIN-CHECK: define void @testU256AddOperation() fn testU256AddOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = add i64 %0, %1 u256 c = a + b; print(c); } // BEGIN-CHECK: define void @testU256AddAssignOperation() fn testU256AddAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = add i64 %0, %1 // CHECK: store i64 %2, ptr %a, align 4 a += b; print(a); } // BEGIN-CHECK: define void @testU256SubOperation() fn testU256SubOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = sub i64 %0, %1 u256 c = a - b; print(c); } // BEGIN-CHECK: define void @testU256SubAssignOperation() fn testU256SubAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = sub i64 %0, %1 // CHECK: store i64 %2, ptr %a, align 4 a -= b; print(a); } // BEGIN-CHECK: define void @testU256MulOperatoin() fn testU256MulOperatoin() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = mul i64 %0, %1 u256 c = a * b; print(c); } // BEGIN-CHECK: define void @testU256MulAssignOperation() fn testU256MulAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = mul i64 %0, %1 // CHECK: store i64 %2, ptr %a, align 4 a *= b; print(a); } // BEGIN-CHECK: define void @testU256DivOperation() fn testU256DivOperation() { u256 a = 10; u256 b = 5; // CHECK: %1 = load i64, ptr %a, align 4 // CHECK: %2 = load i64, ptr %b, align 4 // CHECK: call void @u256_div_mod(i64 %1, i64 %2, ptr %0, ptr null) // CHECK: %3 = load i64, ptr %0, align 4 u256 c = a / b; print(c); } // BEGIN-CHECK: define void @testU256DivAssignOperation() fn testU256DivAssignOperation() { u256 a = 10; u256 b = 5; // CHECK: %1 = load i64, ptr %a, align 4 // CHECK: %2 = load i64, ptr %b, align 4 // CHECK: call void @u256_div_mod(i64 %1, i64 %2, ptr %0, ptr null) // CHECK: %3 = load i64, ptr %0, align 4 // CHECK: store i64 %3, ptr %a, align 4 a /= b; print(a); } // BEGIN-CHECK: define void @testU256ModOperation() fn testU256ModOperation() { u256 a = 10; u256 b = 5; // CHECK: %1 = load i64, ptr %a, align 4 // CHECK: %2 = load i64, ptr %b, align 4 // CHECK: call void @u256_div_mod(i64 %1, i64 %2, ptr null, ptr %0) // CHECK: %3 = load i64, ptr %0, align 4 u256 c = a % b; print(c); } // BEGIN-CHECK: define void @testU256ModAssignOperation() fn testU256ModAssignOperation() { u256 a = 10; u256 b = 5; // CHECK: %1 = load i64, ptr %a, align 4 // CHECK: %2 = load i64, ptr %b, align 4 // CHECK: call void @u256_div_mod(i64 %1, i64 %2, ptr null, ptr %0) // CHECK: %3 = load i64, ptr %0, align 4 // CHECK: store i64 %3, ptr %a, align 4 a %= b; print(a); } // BEGIN-CHECK: define void @testU256BitWiseXorOperation() fn testU256BitWiseXorOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = xor i64 %0, %1 u256 c = a ^ b; print(c); } // BEGIN-CHECK: define void @testU256BitWiseXorAssignOperation() fn testU256BitWiseXorAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = xor i64 %0, %1 // CHECK: store i64 %2, ptr %a, align 4 a ^= b; print(a); } // BEGIN-CHECK: define void @testU256AndOperation() fn testU256AndOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = and i64 %0, %1 u256 c = a & b; print(c); } // BEGIN-CHECK: define void @testU256AndAssignOperation() fn testU256AndAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = and i64 %0, %1 // CHECK: store i64 %2, ptr %a, align 4 a &= b; print(a); } // BEGIN-CHECK: define void @testU256BitWiseOrOperation() fn testU256BitWiseOrOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = or i64 %0, %1 u256 c = a | b; print(c); } // BEGIN-CHECK: define void @testU256BitWiseOrAssignOperation() fn testU256BitWiseOrAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = or i64 %0, %1 // CHECK: store i64 %2, ptr %a, align 4 a |= b; print(a); } // BEGIN-CHECK: define void @testU256PowerOperation() fn testU256PowerOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = call i64 @u256_power(i64 %0, i64 %1) u256 c = a ** b; print(c); } // BEGIN-CHECK: define void @testU256LeftShiftOperation() fn testU256LeftShiftOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = call i64 @u256_power(i64 2, i64 %1) // CHECK: %3 = mul i64 %0, %2 u256 c = a << b; print(c); } // BEGIN-CHECK: define void @testU256LeftShiftAssignOperation() fn testU256LeftShiftAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = call i64 @u256_power(i64 2, i64 %1) // CHECK: %3 = mul i64 %0, %2 // CHECK: store i64 %3, ptr %a, align 4 a <<= b; print(a); } // BEGIN-CHECK: define void @testU256RightShiftOperation() fn testU256RightShiftOperation() { u256 a = 5; u256 b = 10; // CHECK: %1 = load i64, ptr %a, align 4 // CHECK: %2 = load i64, ptr %b, align 4 // CHECK: %3 = call i64 @u256_power(i64 2, i64 %2) // CHECK: call void @u256_div_mod(i64 %1, i64 %3, ptr %0, ptr null) // CHECK: %4 = load i64, ptr %0, align 4 u256 c = a >> b; print(c); } // BEGIN-CHECK: define void @testU256RightShiftAssignOperation() fn testU256RightShiftAssignOperation() { u256 a = 5; u256 b = 10; // CHECK: %1 = load i64, ptr %a, align 4 // CHECK: %2 = load i64, ptr %b, align 4 // CHECK: %3 = call i64 @u256_power(i64 2, i64 %2) // CHECK: call void @u256_div_mod(i64 %1, i64 %3, ptr %0, ptr null) // CHECK: %4 = load i64, ptr %0, align 4 // CHECK: store i64 %4, ptr %a, align 4 a >>= b; print(a); } // BEGIN-CHECK: define void @testU256EqualOperation() fn testU256EqualOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = icmp eq i64 %0, %1 bool c = a == b; print(c); } // BEGIN-CHECK: define void @testU256NotEqualOperation() fn testU256NotEqualOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = icmp ne i64 %0, %1 // CHECK: store i1 %2, ptr %c, align 1 bool c = a != b; print(c); } // BEGIN-CHECK: define void @testU256GreaterOperation() fn testU256GreaterOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = icmp ugt i64 %0, %1 bool c = a > b; print(c); } // BEGIN-CHECK: define void @testU256GreaterEqualOperation() fn testU256GreaterEqualOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = icmp uge i64 %0, %1 bool c = a >= b; print(c); } // BEGIN-CHECK: define void @testU256LessOperation() fn testU256LessOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = icmp ult i64 %0, %1 bool c = a < b; print(c); } // BEGIN-CHECK: define void @testU256LessEqualOperation() fn testU256LessEqualOperation() { u256 a = 5; u256 b = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = icmp ule i64 %0, %1 bool c = a <= b; print(c); } // BEGIN-CHECK: define void @testU256BitWiseNotOperation() fn testU256BitWiseNotOperation() { u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = sub i64 4294967295, %0 u256 c = ~a; print(c); } // BEGIN-CHECK: define void @testU256IncrementOperation() fn testU256IncrementOperation() { u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = add i64 %0, 1 // CHECK: store i64 %1, ptr %a, align 4 a++; print(a); } // BEGIN-CHECK: define void @testU256DecrementOperation() fn testU256DecrementOperation() { u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = sub i64 %0, 1 // CHECK: store i64 %1, ptr %a, align 4 a--; print(a); } // BEGIN-CHECK: define void @testU256AddOverflow() fn testU256AddOverflow() { u256 a = 4294967295; u256 b = 1; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = add i64 %0, %1 // CHECK: call void @builtin_range_check(i64 %2) u256 c = a + b; print(c); } // BEGIN-CHECK: define void @testU256SubOverflow() fn testU256SubOverflow() { u256 a = 0; u256 b = 1; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = load i64, ptr %b, align 4 // CHECK: %2 = sub i64 %0, %1 // CHECK: call void @builtin_range_check(i64 %2) u256 c = a - b; print(c); } // BEGIN-CHECK: define void @testU256ConvertToField() fn testU256ConvertToField() { u256 a = 5; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: store i64 %0, ptr %f, align 4 field f = field(a); print(f); } // BEGIN-CHECK: define void @testU256LocalScope() fn testU256LocalScope() { // CHECK: %a1 = alloca i64, align 8 // CHECK: %a = alloca i64, align 8 { // CHECK: store i64 15, ptr %a, align 4 u256 a = 15; print(a); } // a not found // print(a); // CHECK: store i64 10, ptr %a1, align 4 u256 a = 10; print(a); } // BEGIN-CHECK: define void @testU256IfStatement() fn testU256IfStatement() { u256 a = 10; // CHECK: %0 = load i64, ptr %a, align 4 // CHECK: %1 = icmp ugt i64 %0, 5 // CHECK: br i1 %1, label %then, label %else if (a > 5) { // CHECK: then: // CHECK: %2 = load i64, ptr %a, align 4 print(a); } else { // CHECK: else: // CHECK: br label %endif print(0); } // CHECK: endif: // CHECK: ret void } // BEGIN-CHECK: define void @testU256InLoopStatement() fn testU256InLoopStatement() { // CHECK: %0 = load i64, ptr %i, align 4 // CHECK:%1 = icmp ult i64 %0, 10 // CHECK: br i1 %1, label %body, label %endfor for (u256 i = 0; i < 10; i++) { // CHECK: body: // CHECK: %2 = load i64, ptr %i, align 4 // CHECK: store i64 %2, ptr %a, align 4 u256 a = i; print(a); // CHECK: br label %next } // CHECK: endfor: } }