Please use GitHub pull requests for new patches. Avoid migrating existing patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/test/CodeGen/RISCV/overflow-intrinsics.ll
Show First 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | |||||
; RV64-NEXT: .LBB1_2: | ; RV64-NEXT: .LBB1_2: | ||||
; RV64-NEXT: sd a0, 0(a2) | ; RV64-NEXT: sd a0, 0(a2) | ||||
; RV64-NEXT: mv a0, a1 | ; RV64-NEXT: mv a0, a1 | ||||
; RV64-NEXT: ret | ; RV64-NEXT: ret | ||||
%add = add i64 %b, %a | %add = add i64 %b, %a | ||||
%cmp = icmp ult i64 %add, %a | %cmp = icmp ult i64 %add, %a | ||||
%Q = select i1 %cmp, i64 %b, i64 42 | %Q = select i1 %cmp, i64 %b, i64 42 | ||||
store i64 %add, ptr %res | store i64 %add, ptr %res | ||||
ret i64 %Q | ret i64 %Q | ||||
liaolucy: This can be optimized in riscv DAG combine. I'll write another patch.
to:
```
%add = add i64… | |||||
Not Done ReplyInline ActionsThat doesn't look right. %cmp = icmp ult i64 %b, 0 is always false. There is no value of %b that can less than 0 when treated as unsigned. 0 is the smallest value. craig.topper: That doesn't look right.
```
%cmp = icmp ult i64 %b, 0
```
is always false. There is no value… | |||||
} | } | ||||
define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp { | define i64 @uaddo2_overflow_used(i64 %a, i64 %b) nounwind ssp { | ||||
; RV32-LABEL: uaddo2_overflow_used: | ; RV32-LABEL: uaddo2_overflow_used: | ||||
; RV32: # %bb.0: | ; RV32: # %bb.0: | ||||
; RV32-NEXT: add a1, a3, a1 | ; RV32-NEXT: add a1, a3, a1 | ||||
; RV32-NEXT: add a0, a2, a0 | ; RV32-NEXT: add a0, a2, a0 | ||||
; RV32-NEXT: sltu a0, a0, a2 | ; RV32-NEXT: sltu a0, a0, a2 | ||||
▲ Show 20 Lines • Show All 445 Lines • ▼ Show 20 Lines | ; RV64-NEXT: ret | ||||
%ov = icmp eq i64 %a, 0 | %ov = icmp eq i64 %a, 0 | ||||
store i64 %a, ptr %p | store i64 %a, ptr %p | ||||
ret i1 %ov | ret i1 %ov | ||||
} | } | ||||
define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) { | define i1 @uaddo_i8_increment_noncanonical_1(i8 %x, ptr %p) { | ||||
; RV32-LABEL: uaddo_i8_increment_noncanonical_1: | ; RV32-LABEL: uaddo_i8_increment_noncanonical_1: | ||||
; RV32: # %bb.0: | ; RV32: # %bb.0: | ||||
; RV32-NEXT: andi a0, a0, 255 | |||||
; RV32-NEXT: addi a2, a0, 1 | ; RV32-NEXT: addi a2, a0, 1 | ||||
; RV32-NEXT: andi a0, a2, 255 | ; RV32-NEXT: andi a0, a2, 255 | ||||
; RV32-NEXT: xor a0, a0, a2 | ; RV32-NEXT: seqz a0, a0 | ||||
; RV32-NEXT: snez a0, a0 | |||||
; RV32-NEXT: sb a2, 0(a1) | ; RV32-NEXT: sb a2, 0(a1) | ||||
; RV32-NEXT: ret | ; RV32-NEXT: ret | ||||
; | ; | ||||
; RV64-LABEL: uaddo_i8_increment_noncanonical_1: | ; RV64-LABEL: uaddo_i8_increment_noncanonical_1: | ||||
; RV64: # %bb.0: | ; RV64: # %bb.0: | ||||
; RV64-NEXT: andi a0, a0, 255 | ; RV64-NEXT: addiw a2, a0, 1 | ||||
; RV64-NEXT: addi a2, a0, 1 | |||||
; RV64-NEXT: andi a0, a2, 255 | ; RV64-NEXT: andi a0, a2, 255 | ||||
; RV64-NEXT: xor a0, a0, a2 | ; RV64-NEXT: seqz a0, a0 | ||||
; RV64-NEXT: snez a0, a0 | |||||
; RV64-NEXT: sb a2, 0(a1) | ; RV64-NEXT: sb a2, 0(a1) | ||||
; RV64-NEXT: ret | ; RV64-NEXT: ret | ||||
%a = add i8 1, %x ; commute | %a = add i8 1, %x ; commute | ||||
%ov = icmp eq i8 %a, 0 | %ov = icmp eq i8 %a, 0 | ||||
store i8 %a, ptr %p | store i8 %a, ptr %p | ||||
ret i1 %ov | ret i1 %ov | ||||
} | } | ||||
Show All 15 Lines | ; RV64-NEXT: ret | ||||
%ov = icmp eq i32 0, %a ; commute | %ov = icmp eq i32 0, %a ; commute | ||||
store i32 %a, ptr %p | store i32 %a, ptr %p | ||||
ret i1 %ov | ret i1 %ov | ||||
} | } | ||||
define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) { | define i1 @uaddo_i16_increment_noncanonical_3(i16 %x, ptr %p) { | ||||
; RV32-LABEL: uaddo_i16_increment_noncanonical_3: | ; RV32-LABEL: uaddo_i16_increment_noncanonical_3: | ||||
; RV32: # %bb.0: | ; RV32: # %bb.0: | ||||
; RV32-NEXT: lui a2, 16 | ; RV32-NEXT: addi a2, a0, 1 | ||||
; RV32-NEXT: addi a2, a2, -1 | ; RV32-NEXT: slli a0, a2, 16 | ||||
; RV32-NEXT: and a0, a0, a2 | ; RV32-NEXT: srli a0, a0, 16 | ||||
; RV32-NEXT: addi a3, a0, 1 | ; RV32-NEXT: seqz a0, a0 | ||||
; RV32-NEXT: and a2, a3, a2 | ; RV32-NEXT: sh a2, 0(a1) | ||||
; RV32-NEXT: xor a2, a2, a3 | |||||
; RV32-NEXT: snez a0, a2 | |||||
; RV32-NEXT: sh a3, 0(a1) | |||||
; RV32-NEXT: ret | ; RV32-NEXT: ret | ||||
; | ; | ||||
; RV64-LABEL: uaddo_i16_increment_noncanonical_3: | ; RV64-LABEL: uaddo_i16_increment_noncanonical_3: | ||||
; RV64: # %bb.0: | ; RV64: # %bb.0: | ||||
; RV64-NEXT: lui a2, 16 | ; RV64-NEXT: addiw a2, a0, 1 | ||||
; RV64-NEXT: addiw a2, a2, -1 | ; RV64-NEXT: slli a0, a2, 48 | ||||
; RV64-NEXT: and a0, a0, a2 | ; RV64-NEXT: srli a0, a0, 48 | ||||
; RV64-NEXT: addi a3, a0, 1 | ; RV64-NEXT: seqz a0, a0 | ||||
; RV64-NEXT: and a2, a3, a2 | ; RV64-NEXT: sh a2, 0(a1) | ||||
; RV64-NEXT: xor a2, a2, a3 | |||||
; RV64-NEXT: snez a0, a2 | |||||
; RV64-NEXT: sh a3, 0(a1) | |||||
; RV64-NEXT: ret | ; RV64-NEXT: ret | ||||
%a = add i16 1, %x ; commute | %a = add i16 1, %x ; commute | ||||
%ov = icmp eq i16 0, %a ; commute | %ov = icmp eq i16 0, %a ; commute | ||||
store i16 %a, ptr %p | store i16 %a, ptr %p | ||||
ret i1 %ov | ret i1 %ov | ||||
} | } | ||||
; The overflow check may be against the input rather than the sum. | ; The overflow check may be against the input rather than the sum. | ||||
▲ Show 20 Lines • Show All 656 Lines • ▼ Show 20 Lines | true: | ||||
%svalue = add i64 %key, -1 | %svalue = add i64 %key, -1 | ||||
store i64 %svalue, ptr %p64 | store i64 %svalue, ptr %p64 | ||||
br label %exit | br label %exit | ||||
exit: | exit: | ||||
ret void | ret void | ||||
} | } | ||||
define i16 @overflow_not_used(i16 %a, i16 %b, ptr %res) nounwind ssp { | define i16 @overflow_not_used(i16 %a, i16 %b, ptr %res) { | ||||
; RV32-LABEL: overflow_not_used: | ; RV32-LABEL: overflow_not_used: | ||||
; RV32: # %bb.0: | ; RV32: # %bb.0: | ||||
; RV32-NEXT: lui a3, 16 | ; RV32-NEXT: lui a3, 16 | ||||
; RV32-NEXT: addi a3, a3, -1 | ; RV32-NEXT: addi a3, a3, -1 | ||||
; RV32-NEXT: and a0, a0, a3 | |||||
; RV32-NEXT: and a4, a1, a3 | ; RV32-NEXT: and a4, a1, a3 | ||||
; RV32-NEXT: add a0, a4, a0 | ; RV32-NEXT: add a0, a1, a0 | ||||
; RV32-NEXT: and a3, a0, a3 | ; RV32-NEXT: and a3, a0, a3 | ||||
; RV32-NEXT: bne a3, a0, .LBB37_2 | ; RV32-NEXT: bltu a3, a4, .LBB37_2 | ||||
; RV32-NEXT: # %bb.1: | ; RV32-NEXT: # %bb.1: | ||||
; RV32-NEXT: li a1, 42 | ; RV32-NEXT: li a1, 42 | ||||
; RV32-NEXT: .LBB37_2: | ; RV32-NEXT: .LBB37_2: | ||||
; RV32-NEXT: sh a0, 0(a2) | ; RV32-NEXT: sh a0, 0(a2) | ||||
; RV32-NEXT: mv a0, a1 | ; RV32-NEXT: mv a0, a1 | ||||
; RV32-NEXT: ret | ; RV32-NEXT: ret | ||||
; | ; | ||||
; RV64-LABEL: overflow_not_used: | ; RV64-LABEL: overflow_not_used: | ||||
; RV64: # %bb.0: | ; RV64: # %bb.0: | ||||
; RV64-NEXT: lui a3, 16 | ; RV64-NEXT: lui a3, 16 | ||||
; RV64-NEXT: addiw a3, a3, -1 | ; RV64-NEXT: addiw a3, a3, -1 | ||||
; RV64-NEXT: and a0, a0, a3 | |||||
; RV64-NEXT: and a4, a1, a3 | ; RV64-NEXT: and a4, a1, a3 | ||||
; RV64-NEXT: add a0, a4, a0 | ; RV64-NEXT: add a0, a1, a0 | ||||
; RV64-NEXT: and a3, a0, a3 | ; RV64-NEXT: and a3, a0, a3 | ||||
; RV64-NEXT: bne a3, a0, .LBB37_2 | ; RV64-NEXT: bltu a3, a4, .LBB37_2 | ||||
; RV64-NEXT: # %bb.1: | ; RV64-NEXT: # %bb.1: | ||||
; RV64-NEXT: li a1, 42 | ; RV64-NEXT: li a1, 42 | ||||
; RV64-NEXT: .LBB37_2: | ; RV64-NEXT: .LBB37_2: | ||||
; RV64-NEXT: sh a0, 0(a2) | ; RV64-NEXT: sh a0, 0(a2) | ||||
; RV64-NEXT: mv a0, a1 | ; RV64-NEXT: mv a0, a1 | ||||
; RV64-NEXT: ret | ; RV64-NEXT: ret | ||||
%add = add i16 %b, %a | %add = add i16 %b, %a | ||||
%cmp = icmp ult i16 %add, %b | %cmp = icmp ult i16 %add, %b | ||||
%Q = select i1 %cmp, i16 %b, i16 42 | %Q = select i1 %cmp, i16 %b, i16 42 | ||||
store i16 %add, ptr %res | store i16 %add, ptr %res | ||||
ret i16 %Q | ret i16 %Q | ||||
} | } |
This can be optimized in riscv DAG combine. I'll write another patch.
to: