Closed pzmaus closed 1 year ago
GetElementPtr의 operand op 가 Integer 타입이 아닐 때 버그가 생길 수 있어보입니다.
GetElementPtr의 operand op 가 Integer 타입이 아닐 때 버그가 생길 수 있어보입니다.
답변 감사드립니다. 찾아본 결과 GEP의 index는 integer type말고는 불가능하다고 하는 것 같아 예외처리까지는 하지 않아도 괜찮을 것 같습니다. 제가 테스트해본 예제가 아래와 같은데 , 이것마저도 터지고 있어 이유를 찾지 못하고 있습니다.
define i32 @foo(i32* %arr, i32 %i) {
entry:
%gep = getelementptr i32, i32* %arr, i32 %i
%val = load i32, i32* %gep
ret i32 %val
}
프로그램의 오류가 컴파일 타임에 발생하나요, 인터프리터를 돌릴 때 발생하나요? 또 오류 메시지가 SIGABRT 이외에 따로 없는건가요?
프로그램의 오류가 컴파일 타임에 발생하나요, 인터프리터를 돌릴 때 발생하나요? 또 오류 메시지가 SIGABRT 이외에 따로 없는건가요?
unit_test를 돌리기 위해 ctest --rerun-failed --output-on-failure
를 실행시 나는 에러 전문은 다음과 같습니다.
Test project /home/pzmaus/projects/swpp/project/swpp202301-compiler-team1/build
Start 1: unit_tests
1/1 Test #1: unit_tests .......................***Failed 0.11 sec
== gvn-pass ==
== bias-to-false-branch ==
== add-to-sum ==
== arithmetic-pass ==
== use-async-load ==
== gep_elim ==
Test file: ./unit_tests/gep_elim_1.ll
/home/pzmaus/llvm-swpp/bin/opt -load-pass-plugin=./build/libGEPEliminatePass.so -passes=gep_elim ./unit_tests/gep_elim_1.ll -S -o ./tmp/out.gep_elim_1.ll
Traceback (most recent call last):
File "/home/pzmaus/projects/swpp/project/swpp202301-compiler-team1/unit_tests.py", line 37, in <module>
subprocess.run(opt_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
File "/usr/lib/python3.10/subprocess.py", line 524, in run
raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/home/pzmaus/llvm-swpp/bin/opt', '-load-pass-plugin=./build/libGEPEliminatePass.so', '-passes=gep_elim', './unit_tests/gep_elim_1.ll', '-S', '-o', './tmp/out.gep_elim_1.ll']' died with <Signals.SIGABRT: 6>.
0% tests passed, 1 tests failed out of 1
Total Test time (real) = 0.11 sec
The following tests FAILED:
1 - unit_tests (Failed)
Errors while running CTest
처음에는 entries.csv에 설정을 잘못 기입한줄 알았는데 createMul만 주석처리하면 최적화만 안될 뿐 정상실행되어
define i32 @foo(i32* %arr, i32 %i) {
entry:
%0 = ptrtoint i32* %arr to i64
%1 = inttoptr i64 %0 to i32*
%val = load i32, i32* %1, align 4
ret i32 %val
}
이렇게 출력은 되고있습니다.
/home/pzmaus/llvm-swpp/bin/opt -load-pass-plugin=./build/libGEPEliminatePass.so -passes=gep_elim ./unit_tests/gep_elim_1.ll -S -o ./tmp/out.gep_elim_1.ll
을 한번 실행해 보시고 나온 출력도 확인해보시면 좋을 것 같습니다.
/home/pzmaus/llvm-swpp/bin/opt -load-pass-plugin=./build/libGEPEliminatePass.so -passes=gep_elim ./unit_tests/gep_elim_1.ll -S -o ./tmp/out.gep_elim_1.ll
을 한번 실행해 보시고 나온 출력도 확인해보시면 좋을 것 같습니다.
덕분에 에러를 찾았습니다 감사합니다! 정말 멍청하게도 input test의 문제였습니다....
현재 backend에 있는 gep_eliminate.cpp를 먼저 실행시키는데 있어 어려움을 겪고 있는데 혹시라도 도움을 주실 수 있으신 분이 계신다면 정말 감사드리겠습니다.
backend에 있는 pass는 혼자 작동되는 것보다도 analysis.c , result.h와 같이 엮여있는 코드들이 많아서 이해하는데 오래걸렸는데, 간단하게 요약하면
이렇게 실행되며, 유일하게
const auto size = unwrapOrThrowWithGEP(analysis::tryCalculateSize(curr), *GEPI);
라는 부분만 외부 함수를 필요하는데 결국 curr라는 pointer operand의 type에 알맞는 크기를 가져오는 코드입니다. (i32 이면 4byte, i64 이면 8byte, pointer type이어도 8byte)일단 이렇게 이해를 완료한 뒤 좀더 간단하게 고쳐서 일단 실행이 되도록 만들고 싶어 도전하고 있는데, 현재 어디서 문제가 나는지 알겠지만 왜 문제가 발생하는지 모르겠는 상황입니다.
이게 코드의 전문이나 위에 mul 부분에서 문제가 발생하는 것 같습니다. (저기만 주석처리해도 프로그램이 돌아는 갑니다) llvm::ConstantInt::get를 사용할 때 인자로 상수만 넘겨야되는 것 같아 8UL이라고 상수를 넣었음에도 SIGABRT를 띄우고 종료되어 버립니다. 이외에는 backend에 있는 코드랑 완전히 동일한데.... 혹시라도 이유가 생각나시거나 하실때 알려주시면 감사하겠습니다.
계속 노력해보고 있겠습니다.