Skip to content

Intrinsic replacement for llvm.ssub.sat seems wrong #119

@linnaea

Description

@linnaea

Line 812 of ReplaceUnsupportedIntrinsics.cpp effectively replaces the intrinsic with max(a, b) - b, however if they're signed integers this is incorrect.

Running the following LLVM IR through LLVM's opt utility with -O3 -S shows IGC's replacement is not equivalent to the intrinsic:

declare i8 @llvm.ssub.sat.i8(i8 %a, i8 %b)

define i8 @igc.ssub.sat.i8(i8 %a, i8 %b) {
  %pred = icmp sgt i8 %a, %b
  %op0 = select i1 %pred, i8 %a, i8 %b
  %res = sub i8 %op0, %b
  ret i8 %res
}

define i8 @f() {
  %r1 = call i8 @llvm.ssub.sat.i8(i8 -128, i8 1)
  ret i8 %r1
  ; becomes ret i8 -128
}

define i8 @g() {
  %r1 = call i8 @igc.ssub.sat.i8(i8 -128, i8 1)
  ret i8 %r1
  ; becomes ret i8 0
}

By the way doesn't Gen have native support for ADD.sat? I was digging through the documentation and there's a Saturate bit in EU_INSTRUCTION_CONTROLS_B.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions