-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2253941
commit a00eeef
Showing
38 changed files
with
17,859 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,234 @@ | ||
;! { "cases": [ { | ||
;! "name": "complex_mod", | ||
;! "inputs": [ | ||
;! { | ||
;! "method": "#fallback", | ||
;! "calldata": [ | ||
;! "0x99729a298c414e9c2ea7a37539d5527ff363ccb618b432edde0da847ed417f11" | ||
;! ] | ||
;! } | ||
;! ], | ||
;! "expected": [ | ||
;! "0xdd71feeedc19e712403093645466eb61bdb4502e4d029882f1b3a490c0b838eb" | ||
;! ] | ||
;! } ] } | ||
|
||
|
||
target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256" | ||
target triple = "evm-unknown-unknown" | ||
|
||
define void @test() noreturn { | ||
bb: | ||
%off1 = inttoptr i256 0 to ptr addrspace(2) | ||
%x = call i256 @llvm.evm.calldataload(ptr addrspace(2) %off1) | ||
%a = add i256 0, 115792089210356248762697446949407573530086143415290314195533631308867097853948 | ||
%b = add i256 0, 41058363725152142129326129780047268409114441015993725554835256314039467401291 | ||
%p = add i256 0, 115792089210356248762697446949407573530086143415290314195533631308867097853951 | ||
; mulmod(x, x, p) | ||
%mul1 = call i256 @mulmod(i256 noundef %x, i256 noundef %x, i256 noundef %p) | ||
; mulmod(mulmod(x, x, p), x, p), x^3 | ||
%rhs1 = call i256 @mulmod(i256 noundef %mul1, i256 noundef %x, i256 noundef %p) | ||
; mulmod(x, a, p) | ||
%mul3 = call i256 @mulmod(i256 noundef %x, i256 noundef %a, i256 noundef %p) | ||
; addmod(rhs1, mulmod(x, a, p), p), x^3 + a*x | ||
%rhs2 = call i256 @addmod(i256 noundef %rhs1, i256 noundef %mul3, i256 noundef %p) | ||
; addmod(RHS, b, p), x^3 + a*x + b | ||
%res = call i256 @addmod(i256 noundef %rhs2, i256 noundef %b, i256 noundef %p) | ||
|
||
store i256 %res, ptr addrspace(1) null, align 4 | ||
call void @llvm.evm.return(ptr addrspace(1) null, i256 32) | ||
unreachable | ||
} | ||
|
||
define i256 @addmod(i256 %arg1, i256 %arg2, i256 %modulo) noinline { | ||
entry: | ||
%is_zero = icmp eq i256 %modulo, 0 | ||
br i1 %is_zero, label %return, label %addmod | ||
|
||
addmod: | ||
%arg1m = urem i256 %arg1, %modulo | ||
%arg2m = urem i256 %arg2, %modulo | ||
%res = call {i256, i1} @llvm.uadd.with.overflow.i256(i256 %arg1m, i256 %arg2m) | ||
%sum = extractvalue {i256, i1} %res, 0 | ||
%obit = extractvalue {i256, i1} %res, 1 | ||
%sum.mod = urem i256 %sum, %modulo | ||
br i1 %obit, label %overflow, label %return | ||
|
||
overflow: | ||
%mod.inv = xor i256 %modulo, -1 | ||
%sum1 = add i256 %sum, %mod.inv | ||
%sum.ovf = add i256 %sum1, 1 | ||
br label %return | ||
|
||
return: | ||
%value = phi i256 [0, %entry], [%sum.mod, %addmod], [%sum.ovf, %overflow] | ||
ret i256 %value | ||
} | ||
|
||
define private i256 @clz(i256 %v) noinline { | ||
entry: | ||
%vs128 = lshr i256 %v, 128 | ||
%vs128nz = icmp ne i256 %vs128, 0 | ||
%n128 = select i1 %vs128nz, i256 128, i256 256 | ||
%va128 = select i1 %vs128nz, i256 %vs128, i256 %v | ||
%vs64 = lshr i256 %va128, 64 | ||
%vs64nz = icmp ne i256 %vs64, 0 | ||
%clza64 = sub i256 %n128, 64 | ||
%n64 = select i1 %vs64nz, i256 %clza64, i256 %n128 | ||
%va64 = select i1 %vs64nz, i256 %vs64, i256 %va128 | ||
%vs32 = lshr i256 %va64, 32 | ||
%vs32nz = icmp ne i256 %vs32, 0 | ||
%clza32 = sub i256 %n64, 32 | ||
%n32 = select i1 %vs32nz, i256 %clza32, i256 %n64 | ||
%va32 = select i1 %vs32nz, i256 %vs32, i256 %va64 | ||
%vs16 = lshr i256 %va32, 16 | ||
%vs16nz = icmp ne i256 %vs16, 0 | ||
%clza16 = sub i256 %n32, 16 | ||
%n16 = select i1 %vs16nz, i256 %clza16, i256 %n32 | ||
%va16 = select i1 %vs16nz, i256 %vs16, i256 %va32 | ||
%vs8 = lshr i256 %va16, 8 | ||
%vs8nz = icmp ne i256 %vs8, 0 | ||
%clza8 = sub i256 %n16, 8 | ||
%n8 = select i1 %vs8nz, i256 %clza8, i256 %n16 | ||
%va8 = select i1 %vs8nz, i256 %vs8, i256 %va16 | ||
%vs4 = lshr i256 %va8, 4 | ||
%vs4nz = icmp ne i256 %vs4, 0 | ||
%clza4 = sub i256 %n8, 4 | ||
%n4 = select i1 %vs4nz, i256 %clza4, i256 %n8 | ||
%va4 = select i1 %vs4nz, i256 %vs4, i256 %va8 | ||
%vs2 = lshr i256 %va4, 2 | ||
%vs2nz = icmp ne i256 %vs2, 0 | ||
%clza2 = sub i256 %n4, 2 | ||
%n2 = select i1 %vs2nz, i256 %clza2, i256 %n4 | ||
%va2 = select i1 %vs2nz, i256 %vs2, i256 %va4 | ||
%vs1 = lshr i256 %va2, 1 | ||
%vs1nz = icmp ne i256 %vs1, 0 | ||
%clza1 = sub i256 %n2, 2 | ||
%clzax = sub i256 %n2, %va2 | ||
%result = select i1 %vs1nz, i256 %clza1, i256 %clzax | ||
ret i256 %result | ||
} | ||
|
||
define private i256 @ulongrem(i256 %0, i256 %1, i256 %2) noinline { | ||
%.not = icmp ult i256 %1, %2 | ||
br i1 %.not, label %4, label %51 | ||
|
||
4: | ||
%5 = tail call i256 @clz(i256 %2) | ||
%.not61 = icmp eq i256 %5, 0 | ||
br i1 %.not61, label %13, label %6 | ||
|
||
6: | ||
%7 = shl i256 %2, %5 | ||
%8 = shl i256 %1, %5 | ||
%9 = sub nuw nsw i256 256, %5 | ||
%10 = lshr i256 %0, %9 | ||
%11 = or i256 %10, %8 | ||
%12 = shl i256 %0, %5 | ||
br label %13 | ||
|
||
13: | ||
%.054 = phi i256 [ %7, %6 ], [ %2, %4 ] | ||
%.053 = phi i256 [ %11, %6 ], [ %1, %4 ] | ||
%.052 = phi i256 [ %12, %6 ], [ %0, %4 ] | ||
%14 = lshr i256 %.054, 128 | ||
%15 = udiv i256 %.053, %14 | ||
%16 = urem i256 %.053, %14 | ||
%17 = and i256 %.054, 340282366920938463463374607431768211455 | ||
%18 = lshr i256 %.052, 128 | ||
br label %19 | ||
|
||
19: | ||
%.056 = phi i256 [ %15, %13 ], [ %25, %.critedge ] | ||
%.055 = phi i256 [ %16, %13 ], [ %26, %.critedge ] | ||
%.not62 = icmp ult i256 %.056, 340282366920938463463374607431768211455 | ||
br i1 %.not62, label %20, label %.critedge | ||
|
||
20: | ||
%21 = mul nuw i256 %.056, %17 | ||
%22 = shl nuw i256 %.055, 128 | ||
%23 = or i256 %22, %18 | ||
%24 = icmp ugt i256 %21, %23 | ||
br i1 %24, label %.critedge, label %27 | ||
|
||
.critedge: | ||
%25 = add i256 %.056, -1 | ||
%26 = add i256 %.055, %14 | ||
%.not65 = icmp ult i256 %26, 340282366920938463463374607431768211455 | ||
br i1 %.not65, label %19, label %27 | ||
|
||
27: | ||
%.157 = phi i256 [ %25, %.critedge ], [ %.056, %20 ] | ||
%28 = shl i256 %.053, 128 | ||
%29 = or i256 %18, %28 | ||
%30 = and i256 %.157, 340282366920938463463374607431768211455 | ||
%31 = mul i256 %30, %.054 | ||
%32 = sub i256 %29, %31 | ||
%33 = udiv i256 %32, %14 | ||
%34 = urem i256 %32, %14 | ||
%35 = and i256 %.052, 340282366920938463463374607431768211455 | ||
br label %36 | ||
|
||
36: | ||
%.2 = phi i256 [ %33, %27 ], [ %42, %.critedge1 ] | ||
%.1 = phi i256 [ %34, %27 ], [ %43, %.critedge1 ] | ||
%.not63 = icmp ult i256 %.2, 340282366920938463463374607431768211455 | ||
br i1 %.not63, label %37, label %.critedge1 | ||
|
||
37: | ||
%38 = mul nuw i256 %.2, %17 | ||
%39 = shl i256 %.1, 128 | ||
%40 = or i256 %39, %35 | ||
%41 = icmp ugt i256 %38, %40 | ||
br i1 %41, label %.critedge1, label %44 | ||
|
||
.critedge1: | ||
%42 = add i256 %.2, -1 | ||
%43 = add i256 %.1, %14 | ||
%.not64 = icmp ult i256 %43, 340282366920938463463374607431768211455 | ||
br i1 %.not64, label %36, label %44 | ||
|
||
44: | ||
%.3 = phi i256 [ %42, %.critedge1 ], [ %.2, %37 ] | ||
%45 = shl i256 %32, 128 | ||
%46 = or i256 %45, %35 | ||
%47 = and i256 %.3, 340282366920938463463374607431768211455 | ||
%48 = mul i256 %47, %.054 | ||
%49 = sub i256 %46, %48 | ||
%50 = lshr i256 %49, %5 | ||
br label %51 | ||
|
||
51: | ||
%.0 = phi i256 [ %50, %44 ], [ -1, %3 ] | ||
ret i256 %.0 | ||
} | ||
|
||
define private i256 @mulmod(i256 %arg1, i256 %arg2, i256 %modulo) noinline { | ||
entry: | ||
%cccond = icmp eq i256 %modulo, 0 | ||
br i1 %cccond, label %ccret, label %entrycont | ||
ccret: | ||
ret i256 0 | ||
entrycont: | ||
%arg1m = urem i256 %arg1, %modulo | ||
%arg2m = urem i256 %arg2, %modulo | ||
%less_then_2_128 = icmp ult i256 %modulo, 340282366920938463463374607431768211456 | ||
br i1 %less_then_2_128, label %fast, label %slow | ||
fast: | ||
%prod = mul i256 %arg1m, %arg2m | ||
%prodm = urem i256 %prod, %modulo | ||
ret i256 %prodm | ||
slow: | ||
%arg1e = zext i256 %arg1m to i512 | ||
%arg2e = zext i256 %arg2m to i512 | ||
%prode = mul i512 %arg1e, %arg2e | ||
%prodl = trunc i512 %prode to i256 | ||
%prodeh = lshr i512 %prode, 256 | ||
%prodh = trunc i512 %prodeh to i256 | ||
%res = call i256 @ulongrem(i256 %prodl, i256 %prodh, i256 %modulo) | ||
ret i256 %res | ||
} | ||
|
||
declare {i256, i1} @llvm.uadd.with.overflow.i256(i256, i256) | ||
declare void @llvm.evm.return(ptr addrspace(1), i256) | ||
declare i256 @llvm.evm.calldataload(ptr addrspace(2)) |
Oops, something went wrong.