The SystemZ backend will try to reuse an existing subtraction of two values whenever they are to be compared for equality. This depends on the SystemZ subtraction instruction setting the condition code, which can also signal overflow. A later pass will remove the compare and reuse the CC from the subtraction directly. However, if that subtraction has the NSW flag set it will not include the overflow bit in the updated CC user. That was a bug which can lead to wrong results, as shown by a csmith program. Fixes: https://github.com/llvm/llvm-project/issues/61268 Reviewed By: nikic, uweigand Differential Revision: https://reviews.llvm.org/D145811
40 lines
795 B
LLVM
40 lines
795 B
LLVM
; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z15 | FileCheck %s
|
|
;
|
|
; Test that a CC result of a sub that can overflow is tested with the right predicate.
|
|
|
|
define i32 @fun0(i32 %a, i32 %b, ptr %dest) {
|
|
; CHECK-LABEL: fun0
|
|
; CHECK: s %r2, 0(%r4)
|
|
; CHECK: bner %r14
|
|
entry:
|
|
%cur = load i32, ptr %dest
|
|
%res = sub nsw i32 %a, %cur
|
|
%cmp = icmp ne i32 %a, %cur
|
|
br i1 %cmp, label %exit, label %store
|
|
|
|
store:
|
|
store i32 %b, ptr %dest
|
|
br label %exit
|
|
|
|
exit:
|
|
ret i32 %res
|
|
}
|
|
|
|
define i32 @fun1(i32 %a, i32 %b, ptr %dest) {
|
|
; CHECK-LABEL: fun1
|
|
; CHECK: s %r2, 0(%r4)
|
|
; CHECK: bner %r14
|
|
entry:
|
|
%cur = load i32, ptr %dest
|
|
%res = sub nuw i32 %a, %cur
|
|
%cmp = icmp ne i32 %a, %cur
|
|
br i1 %cmp, label %exit, label %store
|
|
|
|
store:
|
|
store i32 %b, ptr %dest
|
|
br label %exit
|
|
|
|
exit:
|
|
ret i32 %res
|
|
}
|