CS153/hw6/llprograms/sp22_hw3/floyd.ll
jmug 0c04936ccf Updated hw6 to a newer version
Signed-off-by: jmug <u.g.a.mariano@gmail.com>
2025-01-24 21:23:08 -08:00

87 lines
No EOL
3.6 KiB
LLVM

%Node = type { i64, %Node* }
; Small test case with cycle
@test1_n1 = global %Node { i64 1, %Node* @test1_n2 }
@test1_n2 = global %Node { i64 2, %Node* @test1_n3 }
@test1_n3 = global %Node { i64 3, %Node* @test1_n1 }
; Larger test case with cycle
@test2_n1 = global %Node { i64 1, %Node* @test2_n2 }
@test2_n2 = global %Node { i64 2, %Node* @test2_n3 }
@test2_n3 = global %Node { i64 3, %Node* @test2_n4 }
@test2_n4 = global %Node { i64 4, %Node* @test2_n5 }
@test2_n5 = global %Node { i64 5, %Node* @test2_n6 }
@test2_n6 = global %Node { i64 6, %Node* @test2_n7 }
@test2_n7 = global %Node { i64 7, %Node* @test2_n8 }
@test2_n8 = global %Node { i64 8, %Node* @test2_n4 }
; Test case with no cycle
@test3_n1 = global %Node { i64 1, %Node* @test3_n2 }
@test3_n2 = global %Node { i64 2, %Node* @test3_n3 }
@test3_n3 = global %Node { i64 3, %Node* @test3_n4 }
@test3_n4 = global %Node { i64 4, %Node* @test3_n5 }
@test3_n5 = global %Node { i64 5, %Node* @test3_n6 }
@test3_n6 = global %Node { i64 6, %Node* @test3_n7 }
@test3_n7 = global %Node { i64 7, %Node* null }
define i64 @find_cycle(%Node* %head) {
%head_null = icmp eq %Node* %head, null
br i1 %head_null, label %return_false, label %init_pointers
init_pointers:
%tortoise_ptr = alloca %Node*
%hare_ptr = alloca %Node*
store %Node* %head, %Node** %tortoise_ptr
store %Node* %head, %Node** %hare_ptr
br label %check_loop_conds
check_loop_conds:
%tortoise = load %Node*, %Node** %tortoise_ptr
%hare = load %Node*, %Node** %hare_ptr
br label %check_tortoise_next
check_tortoise_next:
%tortoise_link = getelementptr %Node, %Node* %tortoise, i32 0, i32 1
%tortoise_next = load %Node*, %Node** %tortoise_link
%tortoise_next_null = icmp eq %Node* %tortoise_next, null
br i1 %tortoise_next_null, label %return_false, label %check_hare_next
check_hare_next:
%hare_link = getelementptr %Node, %Node* %hare, i32 0, i32 1
%hare_next = load %Node*, %Node** %hare_link
%hare_next_null = icmp eq %Node* %hare_next, null
br i1 %hare_next_null, label %return_false, label %check_hare_next_next
check_hare_next_next:
%hare_next_link = getelementptr %Node, %Node* %hare_next, i32 0, i32 1
%hare_next_next = load %Node*, %Node** %hare_next_link
%hare_next_next_null = icmp eq %Node* %hare_next_next, null
br i1 %hare_next_next_null, label %return_false, label %enter_loop
enter_loop:
%equals = icmp eq %Node* %tortoise_next, %hare_next_next
store %Node* %tortoise_next, %Node** %tortoise_ptr
store %Node* %hare_next_next, %Node** %hare_ptr
br i1 %equals, label %find_first, label %check_loop_conds
find_first:
store %Node* %head, %Node** %tortoise_ptr
br label %check_equals_in_cycle
check_equals_in_cycle:
%tortoise_cycle = load %Node*, %Node** %tortoise_ptr
%hare_cycle = load %Node*, %Node** %hare_ptr
%equals_cycle = icmp eq %Node* %tortoise_cycle, %hare_cycle
br i1 %equals_cycle, label %return_first_cycle_val, label %find_first_loop
find_first_loop:
%tortoise_cycle_link = getelementptr %Node, %Node* %tortoise_cycle, i32 0, i32 1
%tortoise_cycle_next = load %Node*, %Node** %tortoise_cycle_link
store %Node* %tortoise_cycle_next, %Node** %tortoise_ptr
%hare_cycle_link = getelementptr %Node, %Node* %hare_cycle, i32 0, i32 1
%hare_cycle_next = load %Node*, %Node** %hare_cycle_link
store %Node* %hare_cycle_next, %Node** %hare_ptr
br label %check_equals_in_cycle
return_first_cycle_val:
%first_val_ptr = getelementptr %Node, %Node* %tortoise_cycle, i32 0, i32 0
%val = load i64, i64* %first_val_ptr
ret i64 %val
return_false:
ret i64 0
}
define i64 @main(i64 %argc, i8** %arcv) {
%1 = call i64 @find_cycle(%Node* @test2_n1)
ret i64 %1
}