[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