Fail getStridesAndOffset utility instead of asserting during an integer
overflow while computing memref lowering strides. The utility is already
designed to fail in two other scenarios. Update the underlying
makeCanonicalStridedLayoutExpr to fail instead of assert. Asserting
leads to a worse user experience in the conversions layered on top.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Despite this change, LLVM type conversion's convertMemRefType would still assert because it asserts on finding a valid strided type; but this change still makes the situation better.
mlir/lib/IR/BuiltinTypes.cpp | ||
---|---|---|
992–997 | This is checking for the result of undefined behavior (singled integer overflow). I see it was checking that before, but let's not perpetuate this. If we actually want to detect overflow, let's use APInt with quad bitwidth for multiplication and see if the result fits. |
mlir/lib/IR/BuiltinTypes.cpp | ||
---|---|---|
992–997 | Yes, but that's not the purpose of this patch. That can be addressed in a separate patch. This is strictly better on the handling part. |
mlir/lib/IR/BuiltinTypes.cpp | ||
---|---|---|
992–997 | Given that an undefined behavior happens in this flow, there is no guarantee that the error message will be emitted. The compiler may optimize away the branch. This may result in a segfault elsewhere, all depending on the compiler version and optimization flags. I don't see how that is better. We cannot even test reliably. |
mlir/lib/IR/BuiltinTypes.cpp | ||
---|---|---|
992–997 | Wouldn't it have been worse with the assert? (since you won't have it on the release no- assert-build.) This patch is just exposing the issue and keeping the condition ditto. In fact, not exposing this would have more likely perpetuated it. I won't be changing the condition itself and it should be changed in a separate commit. I can rebase on top if someone else wants to fix that. (From the history, the safety check was added by @aartbik.) |
I see asserts as messages for developers that they didn't handle preconditions properly and that the program would eventually crash. A debugging aid that may or may not be there. On the other hand, diagnostics are user-visible messages that should remain consistent across platforms. That's why we have an implicit convention of adding a test for every diagnostics, which would be problematic here. Diagnostics also typically indicate a problem with the IR the user sent to the compiler that the user can act on. While here it is likely that the overflow may be caused by some input IR, there is no indication whether it is indeed the case and how the user can remedy the problem.
This is checking for the result of undefined behavior (singled integer overflow). I see it was checking that before, but let's not perpetuate this. If we actually want to detect overflow, let's use APInt with quad bitwidth for multiplication and see if the result fits.