This is an archive of the discontinued LLVM Phabricator instance.

[BPF] Clean up SelLowering
ClosedPublic

Authored by tamird on Jul 24 2023, 8:48 AM.

Details

Summary

This patch contains a number of uncontroversial changes:

  • Replace all uses of errs, assert, llvm_unreachable with report_fatal_error with informative error strings.
  • Replace calls to fail in loops with at most one call per error instance. Previously a function with 19 arguments would log "too many args" 14 times. This was not helpful.
  • Change one if (..) switch ... to if (..) { switch .... The added brace is consistent with a near-identical switch immediately above.
  • Elide one SDValue copy by using a reference rather than value. This is consistent with a variable declared immediately before it.

Diff Detail

Event Timeline

tamird created this revision.Jul 24 2023, 8:48 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 24 2023, 8:48 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
tamird requested review of this revision.Jul 24 2023, 8:48 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 24 2023, 8:48 AM
arsenm added a subscriber: arsenm.Jul 24 2023, 8:55 AM
arsenm added inline comments.Jul 24 2023, 8:55 AM
llvm/lib/Target/BPF/BPFISelLowering.cpp
41

Don't see the point of using optional with SDValue, it already acts like optional on its own

tamird updated this revision to Diff 543581.Jul 24 2023, 9:12 AM

Remove optional.

tamird marked an inline comment as done.Jul 24 2023, 9:12 AM
ast requested changes to this revision.Jul 24 2023, 9:22 AM
ast added inline comments.
llvm/lib/Target/BPF/BPFISelLowering.cpp
83

Here and elsewhere.
Did you miss Eduard's comment:

This revision now requires changes to proceed.Jul 24 2023, 9:22 AM
tamird updated this revision to Diff 543608.Jul 24 2023, 9:50 AM

Restored unbraced if.

llvm/lib/Target/BPF/BPFISelLowering.cpp
83

I didn't miss it. The description on those guidelines is vague and leaves much in the hands of the author. Anyway, done, I guess.

tamird edited the summary of this revision. (Show Details)Jul 24 2023, 9:58 AM
ast requested changes to this revision.Jul 24 2023, 10:36 AM

I don't see a value in this "cleanup". Looks like code churn to me.

llvm/lib/Target/BPF/BPFISelLowering.cpp
268

and here?

384

pls drop

This revision now requires changes to proceed.Jul 24 2023, 10:36 AM
tamird updated this revision to Diff 543668.Jul 24 2023, 11:58 AM

Unbrace default arms.

I don't see a value in this "cleanup". Looks like code churn to me.

The value is that the current error messages are often misleading or anemic. When working on this code it's extremely painful when the only way to understand what's going on is to step through a debugger because the error messages are just "condition not met" without indicating any of the inputs.

llvm/lib/Target/BPF/BPFISelLowering.cpp
268

Done.

384

Why? This results in a static_cast because the type is not correct.

tamird updated this revision to Diff 543764.Jul 24 2023, 5:53 PM
tamird marked 2 inline comments as done.

Fix test expected message.

ast requested changes to this revision.Jul 25 2023, 9:18 AM

Way too many unrelated changes. Please abandon. Don't see a value in any of them.

This revision now requires changes to proceed.Jul 25 2023, 9:18 AM

Way too many unrelated changes. Please abandon. Don't see a value in any of them.

Can you help me understand why the current shape of this code is better? My position is that this improves the quality of the code and the errors emitted by it as described in an earlier comment. It also brings this file into closer conformance with LLVM coding standards as defined in clang-tidy configs.

tamird updated this revision to Diff 544820.Jul 27 2023, 9:32 AM

revert renaming fail -> unsupported

tamird updated this revision to Diff 544826.Jul 27 2023, 9:47 AM

Reverted clang-tidy changes.

tamird updated this revision to Diff 544827.Jul 27 2023, 9:47 AM

Fix typo.

tamird edited the summary of this revision. (Show Details)Jul 27 2023, 9:47 AM

I left a few minor comments.
All-in-all I think these modifications are fine if it makes BPF backend simpler to work with.
However, I'm not sure if fixing my comments is worthwhile if Alexei objects the whole idea.

llvm/lib/Target/BPF/BPFISelLowering.cpp
46

This prints extra space at the end of the output. I think it should be like this:

if (Val) {
  raw_string_ostream OS(Str);
  OS << ' ';
  Val->print(OS);
}
367–370

This changes semantics a bit, original version has else w/o condition. Looks like the third alternative is VA.isPendingLoc(). I'm not sure if this alternative is possible at this stage, but since we are reporting errors I'd prefer to have "catch-all" else branch.

425–426

I'd say that this change might be smaller:

for (auto &Arg : Outs) {
  ISD::ArgFlagsTy Flags = Arg.Flags;
  if (!Flags.isByVal())
    continue;

  fail(CLI.DL, DAG, "pass by value not supported ", Callee);
  break;
}
545

This was an assert, so let's keep it as report_fatal_error if you want to add some context.

848–849

Please remove braces.

tamird updated this revision to Diff 545256.Jul 28 2023, 1:16 PM

@eddz87 comments.

llvm/lib/Target/BPF/BPFISelLowering.cpp
46

I don't think so; the caller has passed in a message, which we concat on line 50. We need this space so that the user's message doesn't blend in with ours.

367–370

Done.

425–426

Done.

545

Done.

848–849

Done.

eddyz87 added inline comments.Jul 28 2023, 1:29 PM
llvm/lib/Target/BPF/BPFISelLowering.cpp
46

I mean, I checked it before commenting.
If you add, say '|', at the beginning and at the end of OS you'll get output like this:

test3.c:3:10: error: too many arguments|t1: i64 = GlobalAddress<ptr @foo> 0, test3.c:3:10 |
    3 |   return foo(1, 2, 3, 4, 5, 6, 7);
      |          ^
1 error generated.

Note that there is no space after "arguments" and there is an extra space before last |. This is because we are doing Msg.concat(Str), not Str.concat(Msg).

Thanks for addressing the rest of the comments.

tamird updated this revision to Diff 545277.Jul 28 2023, 2:10 PM

Fix diagnostics whitespace.

llvm/lib/Target/BPF/BPFISelLowering.cpp
46

Thanks for explaining! Fixed and tightened up the tests.

ast added a comment.Jul 28 2023, 4:22 PM

I left a few minor comments.
All-in-all I think these modifications are fine if it makes BPF backend simpler to work with.
However, I'm not sure if fixing my comments is worthwhile if Alexei objects the whole idea.

Looks fine to me as well.
@yonghong-song please take a look too.

tamird marked 7 inline comments as done.Jul 28 2023, 6:43 PM
yonghong-song accepted this revision.Jul 29 2023, 10:24 PM

LGTM except one minor suggestion.

llvm/lib/Target/BPF/BPFISelLowering.cpp
379

User may not understand what 'sret' means without looking at source code.
Maybe 'functions with returning struct are not supported'?

tamird added inline comments.Jul 30 2023, 4:16 AM
llvm/lib/Target/BPF/BPFISelLowering.cpp
379

Thanks, I agree this error message is not very clear. I'd like to update it, but I notice that the existing tests do not cover it. Do you know how to write a function that would produce IR with the sret attribute?

eddyz87 added inline comments.Jul 30 2023, 4:39 AM
llvm/lib/Target/BPF/BPFISelLowering.cpp
379

The following C code sample:

struct bar { long a[100]; };
struct bar foo(void) {
  struct bar b;
  return b;
}

Produces IR that triggers the error:

$ clang -mcpu=v4 -O2 --target=bpf -S test3.c -emit-llvm -o -
...
%struct.bar = type { [100 x i64] }

; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none)
define dso_local void @foo(ptr noalias nocapture sret(%struct.bar) align 8 %agg.result) local_unnamed_addr #0 {
entry:
  ret void
}
...
$ clang -mcpu=v4 -O2 --target=bpf -S test3.c -emit-llvm -o - | llc
...
error: <unknown>:0:0: in function foo void (ptr): functions with VarArgs or StructRet are not supported
...
tamird updated this revision to Diff 545424.Jul 30 2023, 4:52 AM

Improve sret message, added test

llvm/lib/Target/BPF/BPFISelLowering.cpp
379

Thanks! Done.

The error message is not what I envisioned.

$ cat t.c
struct t {
   int a;
};
struct t foo(int a, int b) {
  struct t tmp;
  tmp.a = a + b;
  return tmp;
}
$ clang --target=bpf -O2 -g -c t.c
t.c:4:10: error: functions returning through a pointer parameter are not supported
    4 | struct t foo(int a, int b) {
      |          ^
1 error generated.
$

From source code perspective, there is no 'returning through a pointer parameter'.
The source code shows 'returning a struct'.
The error message can be 'functions returning a struct are not supported'.

'union' has the same issue,

$ cat t.c
union t {
   int a;
   int b;
};
union t foo(int a, int b) {
  union t tmp;
  tmp.a = a + b;
  return tmp;
}
$ clang --target=bpf -O2 -g -c t.c
t.c:5:9: error: functions returning through a pointer parameter are not supported
    5 | union t foo(int a, int b) {
      |         ^
1 error generated.
$

In llvm IR, 'union' is represented as 'struct' as well.

If you really want, the error message can be
functions returning a struct/union are not supported.

tamird updated this revision to Diff 545491.Jul 30 2023, 5:29 PM
tamird marked 2 inline comments as done.

Use the same diagnostic for both aggregate return cases.

The error message is not what I envisioned.

$ cat t.c
struct t {
   int a;
};
struct t foo(int a, int b) {
  struct t tmp;
  tmp.a = a + b;
  return tmp;
}
$ clang --target=bpf -O2 -g -c t.c
t.c:4:10: error: functions returning through a pointer parameter are not supported
    4 | struct t foo(int a, int b) {
      |          ^
1 error generated.
$

From source code perspective, there is no 'returning through a pointer parameter'.
The source code shows 'returning a struct'.
The error message can be 'functions returning a struct are not supported'.

'union' has the same issue,

$ cat t.c
union t {
   int a;
   int b;
};
union t foo(int a, int b) {
  union t tmp;
  tmp.a = a + b;
  return tmp;
}
$ clang --target=bpf -O2 -g -c t.c
t.c:5:9: error: functions returning through a pointer parameter are not supported
    5 | union t foo(int a, int b) {
      |         ^
1 error generated.
$

In llvm IR, 'union' is represented as 'struct' as well.

If you really want, the error message can be
functions returning a struct/union are not supported.

Good point; I changed this wording to match the return-struct-in-registers wording. I was trying to distinguish these messages, but there's no need, they are the same from the user's perspective.

Okay, the new error message aggregate returns are not supported looks good to me. thanks!

Could someone land this for me please?

Could someone land this for me please?

I can, will do it a bit later today.

This revision was not accepted when it landed; it landed in state Needs Review.Jul 31 2023, 2:34 PM
Closed by commit rGd542a56c1c2c: [BPF] Clean up SelLowering (authored by tamird, committed by eddyz87). · Explain Why
This revision was automatically updated to reflect the committed changes.
chapuni added inline comments.
llvm/test/CodeGen/BPF/many_args1.ll
3

This doesn't match in -Asserts.

error: <unknown>:0:0: in function foo i32 (i32, i32, i32): 0x55cf2d9bbd90: i64 = GlobalAddress<ptr @bar> 0 too many arguments
tamird added inline comments.Jul 31 2023, 6:17 PM
llvm/test/CodeGen/BPF/many_args1.ll
3

Sorry about that. I haven't been able to reproduce the failure. What cmake flags are you seeing the failure with?

chapuni added inline comments.Jul 31 2023, 6:19 PM
llvm/test/CodeGen/BPF/many_args1.ll
3

Have you tried CMAKE_ENABLE_ASSERTIONS=OFF?

tamird marked 2 inline comments as done.Jul 31 2023, 6:35 PM
tamird added inline comments.
llvm/test/CodeGen/BPF/many_args1.ll
3

Thanks, I thought it defaulted to off. D156769.