I think this kind of thing is done in an LLVM pass generally. Though I’m not sure it’s worth adding. You can just use std::abs() or __builtin_abs, which is way more expressive and basically impossible for the compiler to get wrong.
I’m not a clang expert, but AFAIK generally not. There are a few cases, like zero-initialized arrays that get transformed into intrinsics, but most of the time it’s left to the middle/back-end to generate good code. That part of the compiler is much better at generating good code than the front-end (by design).