snu-sf-class / swpp202401

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

[Project] Skeleton cannot handle `sufflevector` instruction. #150

Open choco-bear opened 1 month ago

choco-bear commented 1 month ago

안녕하세요, [1]은 제가 임의로 작성한 llvm 코드입니다. [1]을 skeleton project를 사용하여 컴파일하려 하면 다음과 같은 에러 메세지와 함께 동작을 정지합니다.

swpp-compiler: /home/doyoung/SWPP/swpp202401/practice-materials/scripts/linux/llvm-project/llvm/include/llvm/Support/Casting.h:109: static bool llvm::isa_impl_cl<llvm::ConstantFP, const llvm::Constant *>::doit(const From *) [To = llvm::ConstantFP, From = const llvm::Constant *]: Assertion `Val && "isa<> used on a null pointer"' failed.
Aborted

shufflevector instruction을 제거하면 문제없이 컴파일에 성공하는 것으로 보아 shufflevector instruction을 처리하지 못하는 것으로 보이는데, 이것이 의도된 사항인지 문의하고자 합니다.

[1]

define void @f(ptr noundef %a, ptr noundef %b, ptr noundef %c, i32 noundef %n) {
entry:
  %b3 = ptrtoint ptr %b to i64
  %c2 = ptrtoint ptr %c to i64
  %a1 = ptrtoint ptr %a to i64
  %0 = add i32 %n, 1
  %min.iters.check = icmp ule i32 %0, 8
  br i1 %min.iters.check, label %scalar.ph, label %vector.memcheck

vector.memcheck:                                  ; preds = %entry
  %1 = sub i64 %a1, %c2
  %diff.check = icmp ult i64 %1, 32
  %2 = sub i64 %b3, %c2
  %diff.check4 = icmp ult i64 %2, 32
  %conflict.rdx = or i1 %diff.check, %diff.check4
  br i1 %conflict.rdx, label %scalar.ph, label %vector.ph

vector.ph:                                        ; preds = %vector.memcheck
  %n.mod.vf = urem i32 %0, 8
  %3 = icmp eq i32 %n.mod.vf, 0
  %4 = select i1 %3, i32 8, i32 %n.mod.vf
  %n.vec = sub i32 %0, %4
  %ind.end = sub i32 %n, %n.vec
  br label %vector.body

vector.body:                                      ; preds = %vector.body, %vector.ph
  %index = phi i32 [ 0, %vector.ph ], [ %index.next, %vector.body ]
  %offset.idx = sub i32 %n, %index
  %5 = add i32 %offset.idx, 0
  %6 = sext i32 %5 to i64
  %7 = getelementptr inbounds i32, ptr %a, i64 %6
  %8 = getelementptr inbounds i32, ptr %7, i32 0
  %9 = getelementptr inbounds i32, ptr %8, i32 -7
  %wide.load = load <8 x i32>, ptr %9, align 4
  %reverse = shufflevector <8 x i32> %wide.load, <8 x i32> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  %10 = sext i32 %5 to i64
  %11 = getelementptr inbounds i32, ptr %b, i64 %10
  %12 = getelementptr inbounds i32, ptr %11, i32 0
  %13 = getelementptr inbounds i32, ptr %12, i32 -7
  %wide.load5 = load <8 x i32>, ptr %13, align 4
  %reverse6 = shufflevector <8 x i32> %wide.load5, <8 x i32> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  %14 = add nsw <8 x i32> %reverse, %reverse6
  %15 = sext i32 %5 to i64
  %16 = getelementptr inbounds i32, ptr %c, i64 %15
  %17 = getelementptr inbounds i32, ptr %16, i32 0
  %18 = getelementptr inbounds i32, ptr %17, i32 -7
  %reverse7 = shufflevector <8 x i32> %14, <8 x i32> poison, <8 x i32> <i32 7, i32 6, i32 5, i32 4, i32 3, i32 2, i32 1, i32 0>
  store <8 x i32> %reverse7, ptr %18, align 4
  %index.next = add nuw i32 %index, 8
  %19 = icmp eq i32 %index.next, %n.vec
  br i1 %19, label %middle.block, label %vector.body, !llvm.loop !5

middle.block:                                     ; preds = %vector.body
  br label %scalar.ph

scalar.ph:                                        ; preds = %vector.memcheck, %entry, %middle.block
  %bc.resume.val = phi i32 [ %ind.end, %middle.block ], [ %n, %entry ], [ %n, %vector.memcheck ]
  br label %for.cond

for.cond:                                         ; preds = %for.inc, %scalar.ph
  %i.0 = phi i32 [ %bc.resume.val, %scalar.ph ], [ %dec, %for.inc ]
  %tobool = icmp ne i32 %i.0, 0
  br i1 %tobool, label %for.body, label %for.cond.cleanup

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

for.body:                                         ; preds = %for.cond
  %idxprom = sext i32 %i.0 to i64
  %arrayidx = getelementptr inbounds i32, ptr %a, i64 %idxprom
  %20 = load i32, ptr %arrayidx, align 4
  %idxprom1 = sext i32 %i.0 to i64
  %arrayidx2 = getelementptr inbounds i32, ptr %b, i64 %idxprom1
  %21 = load i32, ptr %arrayidx2, align 4
  %add = add nsw i32 %20, %21
  %idxprom3 = sext i32 %i.0 to i64
  %arrayidx4 = getelementptr inbounds i32, ptr %c, i64 %idxprom3
  store i32 %add, ptr %arrayidx4, align 4
  br label %for.inc

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

for.end:                                          ; preds = %for.cond.cleanup
  ret void
}

!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, !8}
!6 = !{!"llvm.loop.mustprogress"}
!7 = !{!"llvm.loop.isvectorized", i32 1}
!8 = !{!"llvm.loop.unroll.runtime.disable"}
!9 = distinct !{!9, !6, !7}
strikef commented 1 month ago

네, shufflevector는 지원하지 않습니다. 어떤 형식으로든 (splat이 아닌) 상수 벡터는 백엔드에서 처리하지 못합니다.