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

Reply via email to