[llvm] [LLVM][SVE][CodeGen] Fix incorrect isel for signed saturating instructions. (PR #88136)
Paul Walker via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 11 02:34:44 PDT 2024
================
@@ -1059,6 +1059,20 @@ define <vscale x 16 x i8> @sqadd_b_lowimm(<vscale x 16 x i8> %a) {
ret <vscale x 16 x i8> %out
}
+; Immediate instruction form only supports positive values.
+define <vscale x 16 x i8> @sqadd_b_negimm(<vscale x 16 x i8> %a) {
+; CHECK-LABEL: sqadd_b_negimm:
+; CHECK: // %bb.0:
+; CHECK-NEXT: mov z1.b, #-1 // =0xffffffffffffffff
+; CHECK-NEXT: sqadd z0.b, z0.b, z1.b
+; CHECK-NEXT: ret
+ %elt = insertelement <vscale x 16 x i8> undef, i8 -1, i32 0
----------------
paulwalker-arm wrote:
Splat is not a signed operation and thus is just copies the least significant 8-bits across all lanes. SQADD is a signed operation and thus it interprets `0xFF` as `-1`. Whereas the immediate form treats its immediate operand as unsigned and thus `0xFF` is treated as `256`. For a normal add this would not matter because the 8-bit result would be the same. However for saturating adds the first (correct) interpretation will result in `$reg - 1` saturating at `-128` whereas the latter will always incorrectly result in `$reg + 256 ==> 127` because that is the maximum positive value you can represent in 8-bits.
https://github.com/llvm/llvm-project/pull/88136
More information about the llvm-commits
mailing list