Issue |
141822
|
Summary |
Is CMN safe when the subtraction is nsw?
|
Labels |
new issue
|
Assignees |
|
Reporter |
AZero13
|
In C,
bool cmp(int a, int b) {
return a > -b;
}
yeilds
define i1 @cmn_nsw(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK: // %bb.0:
; CHECK-NEXT: neg w8, w1
; CHECK-NEXT: cmp w0, w8
; CHECK-NEXT: cset w0, gt
; CHECK-NEXT: ret
%sub = sub nsw i32 0, %b
%cmp = icmp sgt i32 %a, %sub
ret i1 %cmp
}
Now, because no fwrapv, the sub is assumed to be nsw.
However, this would mean no signed wrap.
For 0 - b to be signed wrap, b would have to be a value that fits in the realm of possible signed integers, and cause a wrap.
The only value for b that fits is 0x80000000, and therefore:
Iff b is 0x80000000, then 0 - b is signed wrap.
Therefore,
if 0 - b is not signed wrap, or nsw, b is not 0x80000000
Which means in theory I could do this:
define i1 @cmn_nsw(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK: // %bb.0:
; CHECK-NEXT: cmn w0, w1
; CHECK-NEXT: cset w0, gt
; CHECK-NEXT: ret
%sub = sub nsw i32 0, %b
%cmp = icmp sgt i32 %a, %sub
ret i1 %cmp
}
However, alive2 says:
define i1 @src(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK: // %bb.0:
; CHECK-NEXT: cmn w0, w1
; CHECK-NEXT: cset w0, gt
; CHECK-NEXT: ret
%sub = sub nsw i32 0, %b
%cmp = icmp sgt i32 %a, %sub
ret i1 %cmp
}
define i1 @tgt(i32 %a, i32 %b) {
; CHECK-LABEL: cmn_nsw:
; CHECK: // %bb.0:
; CHECK-NEXT: cmn w0, w1
; CHECK-NEXT: cset w0, gt
; CHECK-NEXT: ret
%isNotMin = icmp ne i32 %b, -2147483648
call void @llvm.assume(i1 %isNotMin)
%sub = sub i32 0, %b
%cmp = icmp sgt i32 %a, %sub
ret i1 %cmp
}
ERROR: Source is more defined than target
Example:
i32 %a = #x00000003 (3)
i32 %b = #x80000000 (2147483648, -2147483648)
Source:
i32 %sub = poison
i1 %cmp = poison
Target:
i1 %isNotMin = #x0 (0)
void = UB triggered!
I know I am thinking of multiple levels at once, but the question is, if I am checking if it is safe to turn cmp into cmn, is it safe to just look at the no signed wrap flag?
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs