Skip to content

Conversation

@niaow
Copy link
Member

@niaow niaow commented Dec 31, 2025

This replaces our runtime stringEqual and stringLess functions with calls to libc's memcmp. This has a few advantages:

  1. Memory comparison functions are not duplicated between Go and C
  2. LLVM can optimize the compare-to-empty case by itself, so OptimizeStringEqual is no longer needed
  3. LLVM can rewrite small constant-length memcmp operations into direct loads + compares
  4. Compares to constants are generally compiled into simpler IR

The downside of this is that all of the comparison logic must be handled by the compiler frontend. For string equality checks, we only need to compare the lengths and memcmp if they are equal. String order checks are messier, since we need to:

  1. Find the minimum length
  2. Call memcmp with the minimum length
  3. Compare the lengths
  4. Merge the length comparison with the memory comparison

This replaces our runtime stringEqual and stringLess functions with calls to libc's memcmp.
This has a few advantages:
1. Memory comparison functions are not duplicated between Go and C
2. LLVM can optimize the compare-to-empty case by itself, so OptimizeStringEqual is no longer needed
3. LLVM can rewrite small constant-length memcmp operations into direct loads + compares
4. Compares to constants are generally compiled into simpler IR

The downside of this is that all of the comparison logic must be handled by the compiler frontend.
For string equality checks, we only need to compare the lengths and memcmp if they are equal.
String order checks are messier, since we need to:
1. Find the minimum length
2. Call memcmp with the minimum length
3. Compare the lengths
4. Merge the length comparison with the memory comparison
@niaow niaow added the core label Jan 1, 2026
Copy link
Member

@dgryski dgryski left a comment

Choose a reason for hiding this comment

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

With the exception of the signed/unsigned length question this is probably good to merge. And if it's broken we'll find out soon enough :D

// Calculate the minimum of the two string lengths.
lhsLen := b.CreateExtractValue(lhs, 1, "strlt.lhs.len")
rhsLen := b.CreateExtractValue(rhs, 1, "strlt.rhs.len")
minFnName := "llvm.umin.i" + strconv.Itoa(b.uintptrType.IntTypeWidth())
Copy link
Member

Choose a reason for hiding this comment

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

Aren't string lengths signed?

Copy link
Member Author

@niaow niaow Jan 5, 2026

Choose a reason for hiding this comment

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

The top bit is never set so they are both, although AVR is slightly awkward since the length is actually uintptr.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants