Commit 59ce6153 by Jim Stichnoth

Subzero: Fix sign issues for inlined memset lowering.

For certain cases of inlined memset lowering, the 8-bit value wasn't being properly spread/replicated into the 32-bit immediate to be stored. Specifically, if the 8-bit value is between -128 and -1 (i.e. 0x80 to 0xff), the spread value would be something like 0xffffff80 instead of 0x80808080. BUG= b/30502279 R=jpp@chromium.org Review URL: https://codereview.chromium.org/2215553002 .
parent 58c66b93
......@@ -4980,8 +4980,9 @@ void TargetX86Base<TraitsType>::lowerMemset(Operand *Dest, Operand *Val,
if (shouldOptimizeMemIntrins() && IsCountConst && IsValConst) {
Variable *Base = nullptr;
Variable *VecReg = nullptr;
const uint32_t MaskValue = (ValValue & 0xff);
const uint32_t SpreadValue =
(ValValue << 24) | (ValValue << 16) | (ValValue << 8) | ValValue;
(MaskValue << 24) | (MaskValue << 16) | (MaskValue << 8) | MaskValue;
auto lowerSet = [this, &Base, SpreadValue, &VecReg](Type Ty,
uint32_t OffsetAmt) {
......
......@@ -433,6 +433,24 @@ entry:
; ARM32: uxtb
; ARM32: bl {{.*}} memset
; Same as above, but with a negative value.
define internal void @test_memset_const_neg_val_len_mid(i32 %iptr_dst) {
entry:
%dst = inttoptr i32 %iptr_dst to i8*
call void @llvm.memset.p0i8.i32(i8* %dst, i8 -128, i32 9, i32 1, i1 false)
ret void
}
; CHECK-LABEL: test_memset_const_neg_val_len_mid
; CHECK: mov DWORD PTR [{{.*}}+0x4],0x80808080
; CHECK: mov DWORD PTR [{{.*}}],0x80808080
; CHECK-NEXT: mov BYTE PTR [{{.*}}+0x8],0x80
; CHECK-NOT: mov
; OM1-LABEL: test_memset_const_neg_val_len_mid
; OM1: call {{.*}} R_{{.*}} memset
; ARM32-LABEL: test_memset_const_neg_val_len_mid
; ARM32: uxtb
; ARM32: bl {{.*}} memset
define internal void @test_memset_zero_const_len_small(i32 %iptr_dst) {
entry:
%dst = inttoptr i32 %iptr_dst to i8*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment