snu-sf-class / swpp202401

Principles and Practices of Software Development Main Repository
14 stars 4 forks source link

[Project, Bug Report] Error on Changing block structure #107

Open serverrepairman opened 6 months ago

serverrepairman commented 6 months ago

안녕하세요, 컴파일된 .ll파일을 테스트하는 과정에서 explicit panic이 발생하여 이를 제보합니다.

제가 구현한 Pass는 다음과 같이 if문을 ternary로 대체합니다

if.then: ; preds = %for.body br label %cleanup

if.end: ; preds = %for.body br label %cleanup

cleanup: ; preds = %if.end, %if.then %cleanup.dest.slot.0 = phi i32 [ 1, %if.then ], [ 0, %if.end ] %retval.1 = phi i32 [ 0, %if.then ], [ %retval.0, %if.end ] switch i32 %cleanup.dest.slot.0, label %cleanup6 [ i32 0, label %cleanup.cont ]

* after:

for.body: ; preds = %for.cond %call = call i32 @count(i8 noundef zeroext %val.0, i64 noundef %len, ptr noundef %str1) %call2 = call i32 @count(i8 noundef zeroext %val.0, i64 noundef %len, ptr noundef %str2) %cmp3 = icmp ne i32 %call, %call2 %0 = select i1 %cmp3, i32 1, i32 0 %1 = select i1 %cmp3, i32 0, i32 %retval.0 switch i32 %0, label %cleanup6 [ i32 0, label %cleanup.cont ]


그런데 벤치마크에 있는 anagram.c에 pass를 적용하였을 때 컴파일까지는 제대로 되었으나, 
인터프리터로 test를 진행할 때에는 다음과 같이 explicit panic이 발생하는 것을 확인하였습니다.

[1] 에러 메시지(input1.txt에서 발생)

thread 'main' panicked at src/bin/main.rs:37:9: explicit panic note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

[2] anagram.ll

; ModuleID = 'local/tests/anagram/anagram.ll' source_filename = "/home/serverrepairman/SOGE/project/swpp202401-compiler-team2/local/tests/anagram/anagram.c" target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu"

; Function Attrs: nounwind uwtable define dso_local i32 @count(i8 noundef zeroext %val, i64 noundef %len, ptr noundef %str) #0 { entry: br label %for.cond

for.cond: ; preds = %for.inc, %entry %count.0 = phi i32 [ 0, %entry ], [ %count.1, %for.inc ] %i.0 = phi i32 [ 0, %entry ], [ %inc6, %for.inc ] %conv = sext i32 %i.0 to i64 %cmp = icmp ult i64 %conv, %len br i1 %cmp, label %for.body, label %for.cond.cleanup

for.cond.cleanup: ; preds = %for.cond br label %for.end

for.body: ; preds = %for.cond %conv2 = zext i8 %val to i32 %idxprom = sext i32 %i.0 to i64 %arrayidx = getelementptr inbounds i8, ptr %str, i64 %idxprom %0 = load i8, ptr %arrayidx, align 1 %conv3 = zext i8 %0 to i32 %cmp4 = icmp eq i32 %conv2, %conv3 br i1 %cmp4, label %if.then, label %if.end

if.then: ; preds = %for.body %inc = add nsw i32 %count.0, 1 br label %if.end

if.end: ; preds = %if.then, %for.body %count.1 = phi i32 [ %inc, %if.then ], [ %count.0, %for.body ] br label %for.inc

for.inc: ; preds = %if.end %inc6 = add nsw i32 %i.0, 1 br label %for.cond, !llvm.loop !5

for.end: ; preds = %for.cond.cleanup ret i32 %count.0 }

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1

; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1

; Function Attrs: nounwind uwtable define dso_local i32 @anagram(i64 noundef %len, ptr noundef %str1, ptr noundef %str2) #0 { entry: br label %for.cond

for.cond: ; preds = %for.inc, %entry %val.0 = phi i8 [ 0, %entry ], [ %inc, %for.inc ] %retval.0 = phi i32 [ 0, %entry ], [ %1, %for.inc ] %conv = zext i8 %val.0 to i32 %cmp = icmp slt i32 %conv, 255 br i1 %cmp, label %for.body, label %for.cond.cleanup

for.cond.cleanup: ; preds = %for.cond br label %cleanup6

for.body: ; preds = %for.cond %call = call i32 @count(i8 noundef zeroext %val.0, i64 noundef %len, ptr noundef %str1) %call2 = call i32 @count(i8 noundef zeroext %val.0, i64 noundef %len, ptr noundef %str2) %cmp3 = icmp ne i32 %call, %call2 %0 = select i1 %cmp3, i32 1, i32 0 %1 = select i1 %cmp3, i32 0, i32 %retval.0 switch i32 %0, label %cleanup6 [ i32 0, label %cleanup.cont ]

cleanup.cont: ; preds = %for.body br label %for.inc

for.inc: ; preds = %cleanup.cont %inc = add i8 %val.0, 1 br label %for.cond, !llvm.loop !8

cleanup6: ; preds = %for.body, %for.cond.cleanup %cleanup.dest.slot.1 = phi i32 [ %0, %for.body ], [ 2, %for.cond.cleanup ] %retval.2 = phi i32 [ %1, %for.body ], [ %retval.0, %for.cond.cleanup ] switch i32 %cleanup.dest.slot.1, label %unreachable [ i32 2, label %for.end i32 1, label %return ]

for.end: ; preds = %cleanup6 br label %return

return: ; preds = %for.end, %cleanup6 %retval.3 = phi i32 [ %retval.2, %cleanup6 ], [ 1, %for.end ] ret i32 %retval.3

unreachable: ; preds = %cleanup6 ret i32 0 }

; Function Attrs: nounwind uwtable define dso_local i32 @main() #0 { entry: %call = call i64 (...) @read() %cmp = icmp eq i64 %call, 0 br i1 %cmp, label %if.then, label %if.end

if.then: ; preds = %entry br label %cleanup

if.end: ; preds = %entry %add = add i64 %call, 7 %div = udiv i64 %add, 8 %mul = mul i64 %div, 8 %mul1 = mul i64 %mul, 1 %call2 = call noalias ptr @malloc(i64 noundef %mul1) #4 %add3 = add i64 %call, 7 %div4 = udiv i64 %add3, 8 %mul5 = mul i64 %div4, 8 %mul6 = mul i64 %mul5, 1 %call7 = call noalias ptr @malloc(i64 noundef %mul6) #4 br label %for.cond

for.cond: ; preds = %for.inc, %if.end %i.0 = phi i32 [ 0, %if.end ], [ %inc, %for.inc ] %conv = sext i32 %i.0 to i64 %cmp8 = icmp ult i64 %conv, %call br i1 %cmp8, label %for.body, label %for.cond.cleanup

for.cond.cleanup: ; preds = %for.cond br label %for.end

for.body: ; preds = %for.cond %call10 = call i64 (...) @read() %rem = urem i64 %call10, 256 %conv11 = trunc i64 %rem to i8 %idxprom = sext i32 %i.0 to i64 %arrayidx = getelementptr inbounds i8, ptr %call2, i64 %idxprom store i8 %conv11, ptr %arrayidx, align 1 br label %for.inc

for.inc: ; preds = %for.body %inc = add nsw i32 %i.0, 1 br label %for.cond, !llvm.loop !9

for.end: ; preds = %for.cond.cleanup br label %for.cond13

for.cond13: ; preds = %for.inc24, %for.end %i12.0 = phi i32 [ 0, %for.end ], [ %inc25, %for.inc24 ] %conv14 = sext i32 %i12.0 to i64 %cmp15 = icmp ult i64 %conv14, %call br i1 %cmp15, label %for.body18, label %for.cond.cleanup17

for.cond.cleanup17: ; preds = %for.cond13 br label %for.end26

for.body18: ; preds = %for.cond13 %call19 = call i64 (...) @read() %rem20 = urem i64 %call19, 256 %conv21 = trunc i64 %rem20 to i8 %idxprom22 = sext i32 %i12.0 to i64 %arrayidx23 = getelementptr inbounds i8, ptr %call7, i64 %idxprom22 store i8 %conv21, ptr %arrayidx23, align 1 br label %for.inc24

for.inc24: ; preds = %for.body18 %inc25 = add nsw i32 %i12.0, 1 br label %for.cond13, !llvm.loop !10

for.end26: ; preds = %for.cond.cleanup17 %call27 = call i32 @anagram(i64 noundef %call, ptr noundef %call2, ptr noundef %call7) %conv28 = sext i32 %call27 to i64 call void @write(i64 noundef %conv28) br label %cleanup

cleanup: ; preds = %for.end26, %if.then ret i32 0 }

declare i64 @read(...) #2

; Function Attrs: nounwind allocsize(0) declare noalias ptr @malloc(i64 noundef) #3

declare void @write(i64 noundef) #2

attributes #0 = { nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } attributes #2 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #3 = { nounwind allocsize(0) "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } attributes #4 = { nounwind allocsize(0) }

!llvm.module.flags = !{!0, !1, !2, !3} !llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 4} !1 = !{i32 8, !"PIC Level", i32 2} !2 = !{i32 7, !"PIE Level", i32 2} !3 = !{i32 7, !"uwtable", i32 2} !4 = !{!"clang version 18.1.0rc (https://github.com/llvm/llvm-project.git 461274b81d8641eab64d494accddc81d7db8a09e)"} !5 = distinct !{!5, !6, !7} !6 = !{!"llvm.loop.mustprogress"} !7 = !{!"llvm.loop.unroll.disable"} !8 = distinct !{!8, !6, !7} !9 = distinct !{!9, !6, !7} !10 = distinct !{!10, !6, !7}

[3] anagram.s

start count 3: .entry: r1 = const 0 r2 = const 1 r3 = mul r1 r2 32 r5 = mul r1 r2 32 r4 = const 4294967296 br .for.cond .for.cond: r1 = mul r5 r4 64 r1 = sdiv r1 r4 64 r1 = icmp ult r1 arg2 64 r6 = mul r3 r2 32 br r1 .for.body .for.cond.cleanup .for.cond.cleanup: br .for.end .for.body: r1 = mul r5 r4 64 r1 = sdiv r1 r4 64 r1 = add arg3 r1 64 r1 = load 1 r1 r1 = icmp eq arg1 r1 32 r6 = mul r3 r2 32 br r1 .if.then .if.end .if.then: r6 = add r3 r2 32 br .if.end .if.end: br .for.inc .for.inc: r5 = add r5 r2 32 r3 = mul r6 r2 32 br .for.cond .for.end: ret r6 end count

start anagram 3: .entry: r3 = const 0 r4 = const 1 r7 = mul r3 r4 8 r8 = mul r3 r4 32 r5 = const 255 r6 = const 2 br .for.cond .for.cond: r2 = icmp slt r7 r5 32 r1 = mul r8 r4 32 br r2 .for.body .for.cond.cleanup .for.cond.cleanup: r2 = mul r6 r4 32 r1 = mul r1 r4 32 br .cleanup6 .for.body: r1 = call count r7 arg1 arg2 r2 = call count r7 arg1 arg3 r1 = icmp ne r1 r2 32 br r1 .if.then .if.end .if.then: r1 = mul r4 r4 32 r2 = mul r3 r4 32 br .cleanup .if.end: r1 = mul r3 r4 32 r2 = mul r8 r4 32 br .cleanup .cleanup: r9 = mul r2 r4 32 r8 = mul r1 r4 32 switch r1 0 .cleanup.cont .cleanup6.loopexit .cleanup.cont: br .for.inc .for.inc: r7 = add r7 r4 8 r8 = mul r2 r4 32 br .for.cond .cleanup6.loopexit: r2 = mul r8 r4 32 r1 = mul r9 r4 32 br .cleanup6 .cleanup6: r1 = mul r1 r4 32 switch r2 1 .return 2 .for.end .unreachable .for.end: r1 = mul r4 r4 32 br .return .return: ret r1 .unreachable: ret r3 end anagram

start main 0: .entry: r2 = call read r3 = const 0 r1 = icmp eq r2 r3 64 r4 = const 7 r5 = const 8 r6 = const 1 r7 = const 4294967296 r8 = const 256 r9 = const 255 br r1 .if.then .if.end .if.then: br .cleanup .if.end: r1 = add r2 r4 64 r1 = udiv r1 r5 64 r1 = mul r1 r5 64 r1 = malloc r1 r4 = add r2 r4 64 r4 = udiv r4 r5 64 r4 = mul r4 r5 64 r5 = malloc r4 r10 = mul r3 r6 32 br .for.cond .for.cond: r4 = mul r10 r7 64 r4 = sdiv r4 r7 64 r4 = icmp ult r4 r2 64 br r4 .for.body .for.cond.cleanup .for.cond.cleanup: br .for.end .for.body: r4 = call read r4 = urem r4 r8 64 r11 = and r4 r9 64 r4 = mul r10 r7 64 r4 = sdiv r4 r7 64 r4 = add r1 r4 64 store 1 r11 r4 br .for.inc .for.inc: r10 = add r10 r6 32 br .for.cond .for.end: r10 = mul r3 r6 32 br .for.cond13 .for.cond13: r4 = mul r10 r7 64 r4 = sdiv r4 r7 64 r4 = icmp ult r4 r2 64 br r4 .for.body18 .for.cond.cleanup17 .for.cond.cleanup17: br .for.end26 .for.body18: r4 = call read r4 = urem r4 r8 64 r11 = and r4 r9 64 r4 = mul r10 r7 64 r4 = sdiv r4 r7 64 r4 = add r5 r4 64 store 1 r11 r4 br .for.inc24 .for.inc24: r10 = add r10 r6 32 br .for.cond13 .for.end26: r1 = call anagram r2 r1 r5 r1 = mul r1 r7 64 r1 = sdiv r1 r7 64 call write r1 br .cleanup .cleanup: ret r3 end main

Hyun2023 commented 6 months ago

현재 최신버전 인터프리터에서 첨부해주신 어셈블리는 문제 없이 실행되는걸 확인했습니다.