Commit dd30c81e by Jim Stichnoth

Subzero: Fix sext/zext lowering with i1 source operands.

Also declare a few variables as Constant* instead of Operand* when they hold the result of Ctx->getConstantInt(), to be consistent with the rest of the code. BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/541093002
parent 1d6f0e45
...@@ -1916,22 +1916,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -1916,22 +1916,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// but we're unlikely to see something like that in the bitcode that // but we're unlikely to see something like that in the bitcode that
// the optimizer wouldn't have already taken care of. // the optimizer wouldn't have already taken care of.
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
if (Dest->getType() == IceType_i64) { if (isVectorType(Dest->getType())) {
// t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *T_Lo = makeReg(DestLo->getType());
if (Src0RM->getType() == IceType_i32)
_mov(T_Lo, Src0RM);
else
_movsx(T_Lo, Src0RM);
_mov(DestLo, T_Lo);
Variable *T_Hi = NULL;
Constant *Shift = Ctx->getConstantInt(IceType_i32, 31);
_mov(T_Hi, T_Lo);
_sar(T_Hi, Shift);
_mov(DestHi, T_Hi);
} else if (isVectorType(Dest->getType())) {
Type DestTy = Dest->getType(); Type DestTy = Dest->getType();
if (DestTy == IceType_v16i8) { if (DestTy == IceType_v16i8) {
// onemask = materialize(1,1,...); dst = (src & onemask) > 0 // onemask = materialize(1,1,...); dst = (src & onemask) > 0
...@@ -1953,9 +1938,39 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -1953,9 +1938,39 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
_psra(T, ShiftConstant); _psra(T, ShiftConstant);
_movp(Dest, T); _movp(Dest, T);
} }
} else if (Dest->getType() == IceType_i64) {
// t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2
Constant *Shift = Ctx->getConstantInt(IceType_i32, 31);
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *T_Lo = makeReg(DestLo->getType());
if (Src0RM->getType() == IceType_i32) {
_mov(T_Lo, Src0RM);
} else if (Src0RM->getType() == IceType_i1) {
_mov(T_Lo, Src0RM);
_shl(T_Lo, Shift);
_sar(T_Lo, Shift);
} else {
_movsx(T_Lo, Src0RM);
}
_mov(DestLo, T_Lo);
Variable *T_Hi = NULL;
_mov(T_Hi, T_Lo);
_sar(T_Hi, Shift);
_mov(DestHi, T_Hi);
} else if (Src0RM->getType() == IceType_i1) {
// t1 = src
// shl t1, dst_bitwidth - 1
// sar t1, dst_bitwidth - 1
// dst = t1
size_t DestBits = X86_CHAR_BIT * typeWidthInBytes(Dest->getType());
Constant *ShiftAmount = Ctx->getConstantInt(IceType_i32, DestBits - 1);
Variable *T = NULL;
_mov(T, Src0RM);
_shl(T, ShiftAmount);
_sar(T, ShiftAmount);
_mov(Dest, T);
} else { } else {
// TODO: Sign-extend an i1 via "shl reg, 31; sar reg, 31", and
// also copy to the high operand of a 64-bit variable.
// t1 = movsx src; dst = t1 // t1 = movsx src; dst = t1
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
_movsx(T, Src0RM); _movsx(T, Src0RM);
...@@ -1965,33 +1980,38 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -1965,33 +1980,38 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
} }
case InstCast::Zext: { case InstCast::Zext: {
Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem); Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
if (Dest->getType() == IceType_i64) { if (isVectorType(Dest->getType())) {
// onemask = materialize(1,1,...); dest = onemask & src
Type DestTy = Dest->getType();
Variable *OneMask = makeVectorOfOnes(DestTy);
Variable *T = makeReg(DestTy);
_movp(T, Src0RM);
_pand(T, OneMask);
_movp(Dest, T);
} else if (Dest->getType() == IceType_i64) {
// t1=movzx src; dst.lo=t1; dst.hi=0 // t1=movzx src; dst.lo=t1; dst.hi=0
Constant *Zero = Ctx->getConstantZero(IceType_i32); Constant *Zero = Ctx->getConstantZero(IceType_i32);
Variable *DestLo = llvm::cast<Variable>(loOperand(Dest)); Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest)); Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
Variable *Tmp = makeReg(DestLo->getType()); Variable *Tmp = makeReg(DestLo->getType());
if (Src0RM->getType() == IceType_i32) if (Src0RM->getType() == IceType_i32) {
_mov(Tmp, Src0RM); _mov(Tmp, Src0RM);
else } else if (Src0RM->getType() == IceType_i1) {
Constant *One = Ctx->getConstantInt(IceType_i32, 1);
_mov(Tmp, Src0RM);
_and(Tmp, One);
} else {
_movzx(Tmp, Src0RM); _movzx(Tmp, Src0RM);
}
_mov(DestLo, Tmp); _mov(DestLo, Tmp);
_mov(DestHi, Zero); _mov(DestHi, Zero);
} else if (Src0RM->getType() == IceType_i1) { } else if (Src0RM->getType() == IceType_i1) {
// t = Src0RM; t &= 1; Dest = t // t = Src0RM; t &= 1; Dest = t
Operand *One = Ctx->getConstantInt(IceType_i32, 1); Constant *One = Ctx->getConstantInt(IceType_i32, 1);
Variable *T = makeReg(IceType_i32); Variable *T = makeReg(IceType_i32);
_movzx(T, Src0RM); _movzx(T, Src0RM);
_and(T, One); _and(T, One);
_mov(Dest, T); _mov(Dest, T);
} else if (isVectorType(Dest->getType())) {
// onemask = materialize(1,1,...); dest = onemask & src
Type DestTy = Dest->getType();
Variable *OneMask = makeVectorOfOnes(DestTy);
Variable *T = makeReg(DestTy);
_movp(T, Src0RM);
_pand(T, OneMask);
_movp(Dest, T);
} else { } else {
// t1 = movzx src; dst = t1 // t1 = movzx src; dst = t1
Variable *T = makeReg(Dest->getType()); Variable *T = makeReg(Dest->getType());
...@@ -3920,7 +3940,7 @@ void TargetX8632::lowerSwitch(const InstSwitch *Inst) { ...@@ -3920,7 +3940,7 @@ void TargetX8632::lowerSwitch(const InstSwitch *Inst) {
Src0 = legalize(Src0, Legal_Reg | Legal_Mem, true); Src0 = legalize(Src0, Legal_Reg | Legal_Mem, true);
for (SizeT I = 0; I < NumCases; ++I) { for (SizeT I = 0; I < NumCases; ++I) {
// TODO(stichnot): Correct lowering for IceType_i64. // TODO(stichnot): Correct lowering for IceType_i64.
Operand *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I)); Constant *Value = Ctx->getConstantInt(IceType_i32, Inst->getValue(I));
_cmp(Src0, Value); _cmp(Src0, Value);
_br(InstX8632Br::Br_e, Inst->getLabel(I)); _br(InstX8632Br::Br_e, Inst->getLabel(I));
} }
......
...@@ -650,6 +650,24 @@ entry: ...@@ -650,6 +650,24 @@ entry:
; OPTM1: movsx ; OPTM1: movsx
; OPTM1: sar {{.*}}, 31 ; OPTM1: sar {{.*}}, 31
define internal i64 @sext1To64(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = sext i1 %a.arg_trunc to i64
ret i64 %conv
}
; CHECK-LABEL: sext1To64
; CHECK: mov
; CHECK: shl {{.*}}, 31
; CHECK: sar {{.*}}, 31
; CHECK: sar {{.*}}, 31
;
; OPTM1-LABEL: sext1To64
; OPTM1: mov
; OPTM1: shl {{.*}}, 31
; OPTM1: sar {{.*}}, 31
; OPTM1: sar {{.*}}, 31
define internal i64 @zext32To64(i32 %a) { define internal i64 @zext32To64(i32 %a) {
entry: entry:
%conv = zext i32 %a to i64 %conv = zext i32 %a to i64
...@@ -698,11 +716,11 @@ entry: ...@@ -698,11 +716,11 @@ entry:
ret i64 %conv ret i64 %conv
} }
; CHECK-LABEL: zext1To64 ; CHECK-LABEL: zext1To64
; CHECK: movzx ; CHECK: and {{.*}}, 1
; CHECK: mov {{.*}}, 0 ; CHECK: mov {{.*}}, 0
; ;
; OPTM1-LABEL: zext1To64 ; OPTM1-LABEL: zext1To64
; OPTM1: movzx ; OPTM1: and {{.*}}, 1
; OPTM1: mov {{.*}}, 0 ; OPTM1: mov {{.*}}, 0
define internal void @icmpEq64(i64 %a, i64 %b, i64 %c, i64 %d) { define internal void @icmpEq64(i64 %a, i64 %b, i64 %c, i64 %d) {
......
; Test sext and zext instructions with i1 source operands.
; RUN: %llvm2ice -O2 --verbose none %s \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s
; RUN: %llvm2ice -Om1 --verbose none %s \
; RUN: | llvm-mc -triple=i686-none-nacl -x86-asm-syntax=intel -filetype=obj \
; RUN: | llvm-objdump -d --symbolize -x86-asm-syntax=intel - | FileCheck %s
; RUN: %llvm2ice --verbose none %s | FileCheck --check-prefix=ERRORS %s
; RUN: %llvm2iceinsts %s | %szdiff %s | FileCheck --check-prefix=DUMP %s
; RUN: %llvm2iceinsts --pnacl %s | %szdiff %s \
; RUN: | FileCheck --check-prefix=DUMP %s
define internal i8 @sext1To8(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = sext i1 %a.arg_trunc to i8
ret i8 %conv
}
; CHECK-LABEL: sext1To8
; CHECK: mov
; CHECK: shl {{.*}}, 7
; CHECK: sar {{.*}}, 7
define internal i16 @sext1To16(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = sext i1 %a.arg_trunc to i16
ret i16 %conv
}
; CHECK-LABEL: sext1To16
; CHECK: mov
; CHECK: shl {{.*}}, 15
; CHECK: sar {{.*}}, 15
define internal i32 @sext1To32(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = sext i1 %a.arg_trunc to i32
ret i32 %conv
}
; CHECK-LABEL: sext1To32
; CHECK: mov
; CHECK: shl {{.*}}, 31
; CHECK: sar {{.*}}, 31
define internal i64 @sext1To64(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = sext i1 %a.arg_trunc to i64
ret i64 %conv
}
; CHECK-LABEL: sext1To64
; CHECK: mov
; CHECK: shl {{.*}}, 31
; CHECK: sar {{.*}}, 31
; CHECK: sar {{.*}}, 31
define internal i8 @zext1To8(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = zext i1 %a.arg_trunc to i8
ret i8 %conv
}
; CHECK-LABEL: zext1To8
; CHECK: and {{.*}}, 1
define internal i16 @zext1To16(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = zext i1 %a.arg_trunc to i16
ret i16 %conv
}
; CHECK-LABEL: zext1To16
; CHECK: and {{.*}}, 1
define internal i32 @zext1To32(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = zext i1 %a.arg_trunc to i32
ret i32 %conv
}
; CHECK-LABEL: zext1To32
; CHECK: and {{.*}}, 1
define internal i64 @zext1To64(i32 %a) {
entry:
%a.arg_trunc = trunc i32 %a to i1
%conv = zext i1 %a.arg_trunc to i64
ret i64 %conv
}
; CHECK-LABEL: zext1To64
; CHECK: and {{.*}}, 1
; ERRORS-NOT: ICE translation error
; DUMP-NOT: SZ
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