Skip to content

Add 'unreachable' to LLVM, assume switch is well-formed - #1455

Draft
jiribenes wants to merge 4 commits into
mainfrom
jiribenes/default-unreachable
Draft

Add 'unreachable' to LLVM, assume switch is well-formed#1455
jiribenes wants to merge 4 commits into
mainfrom
jiribenes/default-unreachable

Conversation

@jiribenes

Copy link
Copy Markdown
Contributor

Every match { ... } /* no else */ gets transformed into match { ... } else unreachable on LLVM.

First commit taken from #1434.

@jiribenes

Copy link
Copy Markdown
Contributor Author

I had this ready even before #1440 landed, but now we should be able to finally upstream this.
I think I ran the benchmarks, but I don't have the results written down anywhere (D'oh!)

@jiribenes jiribenes changed the title Add 'unreachable' to LLVM Add 'unreachable' to LLVM, assume switch is well-formed Sep 5, 2026
@jiribenes
jiribenes force-pushed the jiribenes/default-unreachable branch 3 times, most recently from c7bcfa8 to 535d50a Compare September 5, 2026 19:31
@jiribenes
jiribenes force-pushed the jiribenes/default-unreachable branch from 535d50a to 047e7b5 Compare September 5, 2026 19:37
@jiribenes

jiribenes commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

stdlib/set/unique fails in CI, but works on my machine, gotta investigate

==> X effekt.StdlibLLVMTests.examples/stdlib/set/unique.effekt (llvm)  3.201s munit.ComparisonFailException: /home/runner/work/effekt/effekt/effekt/jvm/src/test/scala/effekt/EffektTests.scala:120
119:        test(s"${f.getPath} (${backendName})") {
120:          assertNoDiff(run(f, true), expected)
121:        }
diff assertion failed
=> Diff (- obtained, + expected)
+Cons(Effekt, Cons(after, Cons(and, Cons(around, Cons(ask, Cons(better, Cons(but, Cons(can, Cons(do, Cons(ever, Cons(faster, Cons(fellow, Cons(for, Cons(harder, Cons(hour, Cons(is, Cons(it, Cons(language, Cons(make, Cons(makes, Cons(man, Cons(more, Cons(my, Cons(never, Cons(not, Cons(of, Cons(over, Cons(programmers, Cons(programs, Cons(so, Cons(stronger, Cons(than, Cons(the, Cons(together, Cons(us, Cons(we, Cons(what, Cons(will, Cons(work, Cons(world, Cons(you, Cons(your, Nil()))))))))))))))))))))))))))))))))))))))))))
-[error] Process exited with non-zero exit code 139.
-[error] Valgrind log:
-==5961== Jump to the invalid address stated on the next line
-==5961==    at 0x0: ???
-==5961==    by 0x4037FFF: ??? (in /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
-==5961==    by 0x1FFEFFF49F: ???
-==5961==    by 0x12BAEF: main (main.c:38)
-==5961==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
-==5961== ∙
-==5961== ∙
-==5961== Process terminating with default action of signal 11 (SIGSEGV)
-==5961==  Bad permissions for mapped region at address 0x0
-==5961==    at 0x0: ???
-==5961==    by 0x4037FFF: ??? (in /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2)
-==5961==    by 0x1FFEFFF49F: ???
-==5961==    by 0x12BAEF: main (main.c:38)

Comment on lines +139 to +153
private def showOperand(operand: Operand): (Type, LLVMString) = operand match {
case LocalReference(tpe, name) => (tpe, localName(name))
case ConstantGlobal(name) => (PointerType(), globalName(name))
case ConstantInt(n) => (IntegerType64(), s"$n")
case ConstantByte(n) => (IntegerType8(), s"$n")
case ConstantDouble(n) => (DoubleType(), s"$n")
case ConstantAggregateZero(tpe) => (tpe, "zeroinitializer")
case ConstantNull(tpe) => (tpe, "null")
case ConstantArray(memberType, members) => (ArrayType(members.length, memberType), s"[${commaSeparated(members.map(show))}]")
case ConstantInteger8(b) => (IntegerType8(), s"$b")
}

def show(operand: Operand): LLVMString = operand match {
case LocalReference(tpe, name) => s"${show(tpe)} ${localName(name)}"
case ConstantGlobal(name) => s"ptr ${globalName(name)}"
case ConstantInt(n) => s"i64 $n"
case ConstantByte(n) => s"i8 $n"
case ConstantDouble(n) => s"double $n"
case ConstantAggregateZero(tpe) => s"${show(tpe)} zeroinitializer"
case ConstantNull(tpe) => s"${show(tpe)} null"
case ConstantArray(memberType, members) => s"[${members.length} x ${show(memberType)}] [${commaSeparated(members.map(show))}]"
case ConstantInteger8(b) => s"i8 $b"
def show(operand: Operand): LLVMString = {
val (typ, name) = showOperand(operand)
s"${show(typ)} $name"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like this: some LLVM instructions have only a single type, not a type at every operand...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant