Skip to content

missing switch optimization on by-value vs by-reference parameters #121262

@Jannik2099

Description

@Jannik2099

godbolt https://godbolt.org/z/PcerxzEYh

the code

#include <cerrno>

bool is_good(int ec) {
    if (ec != EINVAL && ec != ENOTSUP &&
        ec != EOPNOTSUPP && ec != ETXTBSY &&
        ec != EXDEV && ec != ENOENT && ec != ENOSYS) {
        return false;
    }
    return true;
}

ends up very different when ec is a reference instead of a value parameter.
The value case fails to optimize this into a switch statement.

reference:

define dso_local noundef zeroext i1 @is_good(int const&)(ptr nocapture noundef nonnull readonly align 4 dereferenceable(4) %ec) local_unnamed_addr {
entry:
  %0 = load i32, ptr %ec, align 4
  switch i32 %0, label %return [
    i32 22, label %if.end
    i32 95, label %if.end
    i32 26, label %if.end
    i32 18, label %if.end
    i32 2, label %if.end
    i32 38, label %if.end
  ]

if.end:
  br label %return

return:
  %retval.0 = phi i1 [ true, %if.end ], [ false, %entry ]
  ret i1 %retval.0
}

value:

define dso_local noundef zeroext i1 @is_good(int)(i32 noundef %ec) local_unnamed_addr {
entry:
  %cmp = icmp eq i32 %ec, 22
  %cmp1 = icmp eq i32 %ec, 95
  %or.cond.not25 = or i1 %cmp, %cmp1
  %0 = and i32 %ec, -9
  %1 = icmp eq i32 %0, 18
  %or.cond14.not24 = or i1 %or.cond.not25, %1
  %cmp9 = icmp eq i32 %ec, 2
  %or.cond15.not23 = or i1 %cmp9, %or.cond14.not24
  %cmp11 = icmp eq i32 %ec, 38
  %or.cond16.not = or i1 %cmp11, %or.cond15.not23
  ret i1 %or.cond16.not
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions