Issue |
130093
|
Summary |
[UBSan][Clang][CodeGen] Improve memory effect modeling of ubsan handlers
|
Labels |
clang:codegen,
missed-optimization
|
Assignees |
|
Reporter |
dtcxzyw
|
Consider the following case: https://godbolt.org/z/zxxn3oG1z
```
; bin/clang -O3 -fsanitize=undefined -S -emit-llvm -o -
int test(int &a, short &c) {
a += c;
return c;
}
```
```
@.src = "" unnamed_addr constant [17 x i8] c"/app/example.cpp\00", align 1
@0 = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
@1 = private unnamed_addr global { { ptr, i32, i32 }, ptr } { { ptr, i32, i32 } { ptr @.src, i32 2, i32 7 }, ptr @0 }
define dso_local noundef range(i32 -32768, 32768) i32 @test(int&, short&)(ptr noundef nonnull align 4 captures(none) dereferenceable(4) %a, ptr noundef nonnull readonly align 2 captures(none) dereferenceable(2) %c) local_unnamed_addr #0 {
entry:
%0 = load i16, ptr %c, align 2
%conv = sext i16 %0 to i32
%1 = load i32, ptr %a, align 4
%2 = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 %1, i32 %conv)
%3 = extractvalue { i32, i1 } %2, 1
br i1 %3, label %handler.add_overflow, label %cont
handler.add_overflow:
%4 = zext i32 %1 to i64
%5 = zext i32 %conv to i64
tail call void @__ubsan_handle_add_overflow(ptr nonnull @1, i64 %4, i64 %5) #3
%.pre = load i16, ptr %c, align 2
%.pre3 = sext i16 %.pre to i32
br label %cont
cont:
%conv1.pre-phi = phi i32 [ %.pre3, %handler.add_overflow ], [ %conv, %entry ]
%6 = extractvalue { i32, i1 } %2, 0
store i32 %6, ptr %a, align 4
ret i32 %conv1.pre-phi
}
declare { i32, i1 } @llvm.sadd.with.overflow.i32(i32, i32) #1
declare void @__ubsan_handle_add_overflow(ptr, i64, i64) local_unnamed_addr #2
attributes #0 = { mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { mustprogress nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #2 = { uwtable }
attributes #3 = { nounwind }
```
If we mark `__ubsan_handle_add_overflow(_abort)` as `memory(argmem: read, inaccessiblemem: readwrite)`, we can avoid reloading `c` after the call to `__ubsan_handle_add_overflow`.
TBH this example doesn't demonstrate a performance issue since we only optimize code in the cold path. However, it would allow more aggressive LICM in the hot path, which improves the performance of fuzzers like AFL.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs