Commit 3ef786f3 by Jim Stichnoth

Subzero: Be more strict about i1 calculations.

One issue is that the test_arith cross test defined functions on i1 but never actually invoked them. Another issue is that the lowering was using 8-bit registers for i1 values, but was being sloppy about leaving stuff in the upper 7 bits, and then using all 8 bits for tests. This takes the approach of explicitly masking the result whenever it's possible for the result to exceed one bit, such as trunc, fptosi, fptoui. Another possibility might be to allow the upper 7 bits to stay sloppy, and explicitly only test the lower bit. Additionally, some "CHECK: ret" lines were removed, since they aren't actually needed after the change to use CHECK-LABEL, and they are affected by an llvm-dump bug (which is fixed in LLVM 3.6). BUG= none R=jvoung@chromium.org Review URL: https://codereview.chromium.org/547033002
parent b63cd886
...@@ -347,6 +347,7 @@ int main(int argc, char **argv) { ...@@ -347,6 +347,7 @@ int main(int argc, char **argv) {
size_t Passes = 0; size_t Passes = 0;
size_t Failures = 0; size_t Failures = 0;
testsInt<bool, bool>(TotalTests, Passes, Failures);
testsInt<uint8_t, myint8_t>(TotalTests, Passes, Failures); testsInt<uint8_t, myint8_t>(TotalTests, Passes, Failures);
testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures); testsInt<uint16_t, int16_t>(TotalTests, Passes, Failures);
testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures); testsInt<uint32_t, int32_t>(TotalTests, Passes, Failures);
......
...@@ -290,6 +290,8 @@ IceString GlobalContext::mangleName(const IceString &Name) const { ...@@ -290,6 +290,8 @@ IceString GlobalContext::mangleName(const IceString &Name) const {
GlobalContext::~GlobalContext() {} GlobalContext::~GlobalContext() {}
Constant *GlobalContext::getConstantInt(Type Ty, uint64_t ConstantInt64) { Constant *GlobalContext::getConstantInt(Type Ty, uint64_t ConstantInt64) {
if (Ty == IceType_i1)
ConstantInt64 &= UINT64_C(1);
return ConstPool->Integers.getOrAdd(this, Ty, ConstantInt64); return ConstPool->Integers.getOrAdd(this, Ty, ConstantInt64);
} }
......
...@@ -1947,7 +1947,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -1947,7 +1947,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
if (Src0RM->getType() == IceType_i32) { if (Src0RM->getType() == IceType_i32) {
_mov(T_Lo, Src0RM); _mov(T_Lo, Src0RM);
} else if (Src0RM->getType() == IceType_i1) { } else if (Src0RM->getType() == IceType_i1) {
_mov(T_Lo, Src0RM); _movzx(T_Lo, Src0RM);
_shl(T_Lo, Shift); _shl(T_Lo, Shift);
_sar(T_Lo, Shift); _sar(T_Lo, Shift);
} else { } else {
...@@ -1956,7 +1956,9 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -1956,7 +1956,9 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
_mov(DestLo, T_Lo); _mov(DestLo, T_Lo);
Variable *T_Hi = NULL; Variable *T_Hi = NULL;
_mov(T_Hi, T_Lo); _mov(T_Hi, T_Lo);
_sar(T_Hi, Shift); if (Src0RM->getType() != IceType_i1)
// For i1, the sar instruction is already done above.
_sar(T_Hi, Shift);
_mov(DestHi, T_Hi); _mov(DestHi, T_Hi);
} else if (Src0RM->getType() == IceType_i1) { } else if (Src0RM->getType() == IceType_i1) {
// t1 = src // t1 = src
...@@ -1965,8 +1967,15 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -1965,8 +1967,15 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// dst = t1 // dst = t1
size_t DestBits = X86_CHAR_BIT * typeWidthInBytes(Dest->getType()); size_t DestBits = X86_CHAR_BIT * typeWidthInBytes(Dest->getType());
Constant *ShiftAmount = Ctx->getConstantInt(IceType_i32, DestBits - 1); Constant *ShiftAmount = Ctx->getConstantInt(IceType_i32, DestBits - 1);
Variable *T = NULL; Variable *T = makeReg(Dest->getType());
_mov(T, Src0RM); if (typeWidthInBytes(Dest->getType()) <=
typeWidthInBytes(Src0RM->getType())) {
_mov(T, Src0RM);
} else {
// Widen the source using movsx or movzx. (It doesn't matter
// which one, since the following shl/sar overwrite the bits.)
_movzx(T, Src0RM);
}
_shl(T, ShiftAmount); _shl(T, ShiftAmount);
_sar(T, ShiftAmount); _sar(T, ShiftAmount);
_mov(Dest, T); _mov(Dest, T);
...@@ -1996,13 +2005,13 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -1996,13 +2005,13 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
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 if (Src0RM->getType() == IceType_i1) {
Constant *One = Ctx->getConstantInt(IceType_i32, 1);
_mov(Tmp, Src0RM);
_and(Tmp, One);
} else { } else {
_movzx(Tmp, Src0RM); _movzx(Tmp, Src0RM);
} }
if (Src0RM->getType() == IceType_i1) {
Constant *One = Ctx->getConstantInt(IceType_i32, 1);
_and(Tmp, One);
}
_mov(DestLo, Tmp); _mov(DestLo, Tmp);
_mov(DestHi, Zero); _mov(DestHi, Zero);
} else if (Src0RM->getType() == IceType_i1) { } else if (Src0RM->getType() == IceType_i1) {
...@@ -2038,6 +2047,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -2038,6 +2047,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// t1 = trunc Src0RM; Dest = t1 // t1 = trunc Src0RM; Dest = t1
Variable *T = NULL; Variable *T = NULL;
_mov(T, Src0RM); _mov(T, Src0RM);
if (Dest->getType() == IceType_i1)
_and(T, Ctx->getConstantInt(IceType_i1, 1));
_mov(Dest, T); _mov(Dest, T);
} }
break; break;
...@@ -2081,6 +2092,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -2081,6 +2092,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
Variable *T_2 = makeReg(Dest->getType()); Variable *T_2 = makeReg(Dest->getType());
_cvtt(T_1, Src0RM); _cvtt(T_1, Src0RM);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types _mov(T_2, T_1); // T_1 and T_2 may have different integer types
if (Dest->getType() == IceType_i1)
_and(T_2, Ctx->getConstantInt(IceType_i1, 1));
_mov(Dest, T_2); _mov(Dest, T_2);
T_2->setPreferredRegister(T_1, true); T_2->setPreferredRegister(T_1, true);
} }
...@@ -2116,6 +2129,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) { ...@@ -2116,6 +2129,8 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
Variable *T_2 = makeReg(Dest->getType()); Variable *T_2 = makeReg(Dest->getType());
_cvtt(T_1, Src0RM); _cvtt(T_1, Src0RM);
_mov(T_2, T_1); // T_1 and T_2 may have different integer types _mov(T_2, T_1); // T_1 and T_2 may have different integer types
if (Dest->getType() == IceType_i1)
_and(T_2, Ctx->getConstantInt(IceType_i1, 1));
_mov(Dest, T_2); _mov(Dest, T_2);
T_2->setPreferredRegister(T_1, true); T_2->setPreferredRegister(T_1, true);
} }
......
...@@ -127,12 +127,10 @@ entry: ...@@ -127,12 +127,10 @@ entry:
; CHECK-LABEL: return64BitArg ; CHECK-LABEL: return64BitArg
; CHECK: mov {{.*}}, dword ptr [esp + 4] ; CHECK: mov {{.*}}, dword ptr [esp + 4]
; CHECK: mov {{.*}}, dword ptr [esp + 8] ; CHECK: mov {{.*}}, dword ptr [esp + 8]
; CHECK: ret
; ;
; OPTM1-LABEL: return64BitArg ; OPTM1-LABEL: return64BitArg
; OPTM1: mov {{.*}}, dword ptr [esp + 4] ; OPTM1: mov {{.*}}, dword ptr [esp + 4]
; OPTM1: mov {{.*}}, dword ptr [esp + 8] ; OPTM1: mov {{.*}}, dword ptr [esp + 8]
; OPTM1: ret
define internal i64 @return64BitConst() { define internal i64 @return64BitConst() {
entry: entry:
...@@ -141,12 +139,10 @@ entry: ...@@ -141,12 +139,10 @@ entry:
; CHECK-LABEL: return64BitConst ; CHECK-LABEL: return64BitConst
; CHECK: mov eax, 305419896 ; CHECK: mov eax, 305419896
; CHECK: mov edx, 3735928559 ; CHECK: mov edx, 3735928559
; CHECK: ret
; ;
; OPTM1-LABEL: return64BitConst ; OPTM1-LABEL: return64BitConst
; OPTM1: mov eax, 305419896 ; OPTM1: mov eax, 305419896
; OPTM1: mov edx, 3735928559 ; OPTM1: mov edx, 3735928559
; OPTM1: ret
define internal i64 @add64BitSigned(i64 %a, i64 %b) { define internal i64 @add64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -156,12 +152,10 @@ entry: ...@@ -156,12 +152,10 @@ entry:
; CHECK-LABEL: add64BitSigned ; CHECK-LABEL: add64BitSigned
; CHECK: add ; CHECK: add
; CHECK: adc ; CHECK: adc
; CHECK: ret
; ;
; OPTM1-LABEL: add64BitSigned ; OPTM1-LABEL: add64BitSigned
; OPTM1: add ; OPTM1: add
; OPTM1: adc ; OPTM1: adc
; OPTM1: ret
define internal i64 @add64BitUnsigned(i64 %a, i64 %b) { define internal i64 @add64BitUnsigned(i64 %a, i64 %b) {
entry: entry:
...@@ -171,12 +165,10 @@ entry: ...@@ -171,12 +165,10 @@ entry:
; CHECK-LABEL: add64BitUnsigned ; CHECK-LABEL: add64BitUnsigned
; CHECK: add ; CHECK: add
; CHECK: adc ; CHECK: adc
; CHECK: ret
; ;
; OPTM1-LABEL: add64BitUnsigned ; OPTM1-LABEL: add64BitUnsigned
; OPTM1: add ; OPTM1: add
; OPTM1: adc ; OPTM1: adc
; OPTM1: ret
define internal i64 @sub64BitSigned(i64 %a, i64 %b) { define internal i64 @sub64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -186,12 +178,10 @@ entry: ...@@ -186,12 +178,10 @@ entry:
; CHECK-LABEL: sub64BitSigned ; CHECK-LABEL: sub64BitSigned
; CHECK: sub ; CHECK: sub
; CHECK: sbb ; CHECK: sbb
; CHECK: ret
; ;
; OPTM1-LABEL: sub64BitSigned ; OPTM1-LABEL: sub64BitSigned
; OPTM1: sub ; OPTM1: sub
; OPTM1: sbb ; OPTM1: sbb
; OPTM1: ret
define internal i64 @sub64BitUnsigned(i64 %a, i64 %b) { define internal i64 @sub64BitUnsigned(i64 %a, i64 %b) {
entry: entry:
...@@ -201,12 +191,10 @@ entry: ...@@ -201,12 +191,10 @@ entry:
; CHECK-LABEL: sub64BitUnsigned ; CHECK-LABEL: sub64BitUnsigned
; CHECK: sub ; CHECK: sub
; CHECK: sbb ; CHECK: sbb
; CHECK: ret
; ;
; OPTM1-LABEL: sub64BitUnsigned ; OPTM1-LABEL: sub64BitUnsigned
; OPTM1: sub ; OPTM1: sub
; OPTM1: sbb ; OPTM1: sbb
; OPTM1: ret
define internal i64 @mul64BitSigned(i64 %a, i64 %b) { define internal i64 @mul64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -219,7 +207,6 @@ entry: ...@@ -219,7 +207,6 @@ entry:
; CHECK: mul ; CHECK: mul
; CHECK: add ; CHECK: add
; CHECK: add ; CHECK: add
; CHECK: ret
; ;
; OPTM1-LABEL: mul64BitSigned ; OPTM1-LABEL: mul64BitSigned
; OPTM1: imul ; OPTM1: imul
...@@ -227,7 +214,6 @@ entry: ...@@ -227,7 +214,6 @@ entry:
; OPTM1: mul ; OPTM1: mul
; OPTM1: add ; OPTM1: add
; OPTM1: add ; OPTM1: add
; OPTM1: ret
define internal i64 @mul64BitUnsigned(i64 %a, i64 %b) { define internal i64 @mul64BitUnsigned(i64 %a, i64 %b) {
entry: entry:
...@@ -240,7 +226,6 @@ entry: ...@@ -240,7 +226,6 @@ entry:
; CHECK: mul ; CHECK: mul
; CHECK: add ; CHECK: add
; CHECK: add ; CHECK: add
; CHECK: ret
; ;
; OPTM1-LABEL: mul64BitUnsigned ; OPTM1-LABEL: mul64BitUnsigned
; OPTM1: imul ; OPTM1: imul
...@@ -248,7 +233,6 @@ entry: ...@@ -248,7 +233,6 @@ entry:
; OPTM1: mul ; OPTM1: mul
; OPTM1: add ; OPTM1: add
; OPTM1: add ; OPTM1: add
; OPTM1: ret
define internal i64 @div64BitSigned(i64 %a, i64 %b) { define internal i64 @div64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -259,11 +243,9 @@ entry: ...@@ -259,11 +243,9 @@ entry:
; CALLTARGETS-LABEL: div64BitSigned ; CALLTARGETS-LABEL: div64BitSigned
; CHECK: call -4 ; CHECK: call -4
; CALLTARGETS: call __divdi3 ; CALLTARGETS: call __divdi3
; CHECK: ret
; OPTM1-LABEL: div64BitSigned ; OPTM1-LABEL: div64BitSigned
; OPTM1: call -4 ; OPTM1: call -4
; OPTM1: ret
define internal i64 @div64BitSignedConst(i64 %a) { define internal i64 @div64BitSignedConst(i64 %a) {
entry: entry:
...@@ -276,13 +258,11 @@ entry: ...@@ -276,13 +258,11 @@ entry:
; CHECK: mov dword ptr [esp + 8], 1942892530 ; CHECK: mov dword ptr [esp + 8], 1942892530
; CHECK: call -4 ; CHECK: call -4
; CALLTARGETS: call __divdi3 ; CALLTARGETS: call __divdi3
; CHECK: ret
; ;
; OPTM1-LABEL: div64BitSignedConst ; OPTM1-LABEL: div64BitSignedConst
; OPTM1: mov dword ptr [esp + 12], 2874 ; OPTM1: mov dword ptr [esp + 12], 2874
; OPTM1: mov dword ptr [esp + 8], 1942892530 ; OPTM1: mov dword ptr [esp + 8], 1942892530
; OPTM1: call -4 ; OPTM1: call -4
; OPTM1: ret
define internal i64 @div64BitUnsigned(i64 %a, i64 %b) { define internal i64 @div64BitUnsigned(i64 %a, i64 %b) {
entry: entry:
...@@ -293,11 +273,9 @@ entry: ...@@ -293,11 +273,9 @@ entry:
; CALLTARGETS-LABEL: div64BitUnsigned ; CALLTARGETS-LABEL: div64BitUnsigned
; CHECK: call -4 ; CHECK: call -4
; CALLTARGETS: call __udivdi3 ; CALLTARGETS: call __udivdi3
; CHECK: ret
; ;
; OPTM1-LABEL: div64BitUnsigned ; OPTM1-LABEL: div64BitUnsigned
; OPTM1: call -4 ; OPTM1: call -4
; OPTM1: ret
define internal i64 @rem64BitSigned(i64 %a, i64 %b) { define internal i64 @rem64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -308,11 +286,9 @@ entry: ...@@ -308,11 +286,9 @@ entry:
; CALLTARGETS-LABEL: rem64BitSigned ; CALLTARGETS-LABEL: rem64BitSigned
; CHECK: call -4 ; CHECK: call -4
; CALLTARGETS: call __moddi3 ; CALLTARGETS: call __moddi3
; CHECK: ret
; ;
; OPTM1-LABEL: rem64BitSigned ; OPTM1-LABEL: rem64BitSigned
; OPTM1: call -4 ; OPTM1: call -4
; OPTM1: ret
define internal i64 @rem64BitUnsigned(i64 %a, i64 %b) { define internal i64 @rem64BitUnsigned(i64 %a, i64 %b) {
entry: entry:
...@@ -323,11 +299,9 @@ entry: ...@@ -323,11 +299,9 @@ entry:
; CALLTARGETS-LABEL: rem64BitUnsigned ; CALLTARGETS-LABEL: rem64BitUnsigned
; CHECK: call -4 ; CHECK: call -4
; CALLTARGETS: call __umoddi3 ; CALLTARGETS: call __umoddi3
; CHECK: ret
; ;
; OPTM1-LABEL: rem64BitUnsigned ; OPTM1-LABEL: rem64BitUnsigned
; OPTM1: call -4 ; OPTM1: call -4
; OPTM1: ret
define internal i64 @shl64BitSigned(i64 %a, i64 %b) { define internal i64 @shl64BitSigned(i64 %a, i64 %b) {
entry: entry:
...@@ -484,11 +458,9 @@ entry: ...@@ -484,11 +458,9 @@ entry:
} }
; CHECK-LABEL: trunc64To32Signed ; CHECK-LABEL: trunc64To32Signed
; CHECK: mov eax, dword ptr [esp + 4] ; CHECK: mov eax, dword ptr [esp + 4]
; CHECK-NEXT: ret
; ;
; OPTM1-LABEL: trunc64To32Signed ; OPTM1-LABEL: trunc64To32Signed
; OPTM1: mov eax, dword ptr [esp + ; OPTM1: mov eax, dword ptr [esp +
; OPTM1: ret
define internal i32 @trunc64To16Signed(i64 %a) { define internal i32 @trunc64To16Signed(i64 %a) {
entry: entry:
...@@ -499,12 +471,10 @@ entry: ...@@ -499,12 +471,10 @@ entry:
; CHECK-LABEL: trunc64To16Signed ; CHECK-LABEL: trunc64To16Signed
; CHECK: mov eax, dword ptr [esp + 4] ; CHECK: mov eax, dword ptr [esp + 4]
; CHECK-NEXT: movsx eax, ax ; CHECK-NEXT: movsx eax, ax
; CHECK-NEXT: ret
; ;
; OPTM1-LABEL: trunc64To16Signed ; OPTM1-LABEL: trunc64To16Signed
; OPTM1: mov eax, dword ptr [esp + ; OPTM1: mov eax, dword ptr [esp +
; OPTM1: movsx eax, ; OPTM1: movsx eax,
; OPTM1: ret
define internal i32 @trunc64To8Signed(i64 %a) { define internal i32 @trunc64To8Signed(i64 %a) {
entry: entry:
...@@ -515,12 +485,10 @@ entry: ...@@ -515,12 +485,10 @@ entry:
; CHECK-LABEL: trunc64To8Signed ; CHECK-LABEL: trunc64To8Signed
; CHECK: mov eax, dword ptr [esp + 4] ; CHECK: mov eax, dword ptr [esp + 4]
; CHECK-NEXT: movsx eax, al ; CHECK-NEXT: movsx eax, al
; CHECK-NEXT: ret
; ;
; OPTM1-LABEL: trunc64To8Signed ; OPTM1-LABEL: trunc64To8Signed
; OPTM1: mov eax, dword ptr [esp + ; OPTM1: mov eax, dword ptr [esp +
; OPTM1: movsx eax, ; OPTM1: movsx eax,
; OPTM1: ret
define internal i32 @trunc64To32SignedConst() { define internal i32 @trunc64To32SignedConst() {
entry: entry:
...@@ -554,11 +522,9 @@ entry: ...@@ -554,11 +522,9 @@ entry:
} }
; CHECK-LABEL: trunc64To32Unsigned ; CHECK-LABEL: trunc64To32Unsigned
; CHECK: mov eax, dword ptr [esp + 4] ; CHECK: mov eax, dword ptr [esp + 4]
; CHECK-NEXT: ret
; ;
; OPTM1-LABEL: trunc64To32Unsigned ; OPTM1-LABEL: trunc64To32Unsigned
; OPTM1: mov eax, dword ptr [esp + ; OPTM1: mov eax, dword ptr [esp +
; OPTM1: ret
define internal i32 @trunc64To16Unsigned(i64 %a) { define internal i32 @trunc64To16Unsigned(i64 %a) {
entry: entry:
...@@ -569,12 +535,10 @@ entry: ...@@ -569,12 +535,10 @@ entry:
; CHECK-LABEL: trunc64To16Unsigned ; CHECK-LABEL: trunc64To16Unsigned
; CHECK: mov eax, dword ptr [esp + 4] ; CHECK: mov eax, dword ptr [esp + 4]
; CHECK-NEXT: movzx eax, ax ; CHECK-NEXT: movzx eax, ax
; CHECK-NEXT: ret
; ;
; OPTM1-LABEL: trunc64To16Unsigned ; OPTM1-LABEL: trunc64To16Unsigned
; OPTM1: mov eax, dword ptr [esp + ; OPTM1: mov eax, dword ptr [esp +
; OPTM1: movzx eax, ; OPTM1: movzx eax,
; OPTM1: ret
define internal i32 @trunc64To8Unsigned(i64 %a) { define internal i32 @trunc64To8Unsigned(i64 %a) {
entry: entry:
...@@ -585,12 +549,10 @@ entry: ...@@ -585,12 +549,10 @@ entry:
; CHECK-LABEL: trunc64To8Unsigned ; CHECK-LABEL: trunc64To8Unsigned
; CHECK: mov eax, dword ptr [esp + 4] ; CHECK: mov eax, dword ptr [esp + 4]
; CHECK-NEXT: movzx eax, al ; CHECK-NEXT: movzx eax, al
; CHECK-NEXT: ret
; ;
; OPTM1-LABEL: trunc64To8Unsigned ; OPTM1-LABEL: trunc64To8Unsigned
; OPTM1: mov eax, dword ptr [esp + ; OPTM1: mov eax, dword ptr [esp +
; OPTM1: movzx eax, ; OPTM1: movzx eax,
; OPTM1: ret
define internal i32 @trunc64To1(i64 %a) { define internal i32 @trunc64To1(i64 %a) {
entry: entry:
...@@ -602,12 +564,12 @@ entry: ...@@ -602,12 +564,12 @@ entry:
; CHECK-LABEL: trunc64To1 ; CHECK-LABEL: trunc64To1
; CHECK: mov eax, dword ptr [esp + 4] ; CHECK: mov eax, dword ptr [esp + 4]
; CHECK: and eax, 1 ; CHECK: and eax, 1
; CHECK-NEXT: ret ; CHECK: and eax, 1
; ;
; OPTM1-LABEL: trunc64To1 ; OPTM1-LABEL: trunc64To1
; OPTM1: mov eax, dword ptr [esp + ; OPTM1: mov eax, dword ptr [esp +
; OPTM1: and eax, 1 ; OPTM1: and eax, 1
; OPTM1: ret ; OPTM1: and eax, 1
define internal i64 @sext32To64(i32 %a) { define internal i64 @sext32To64(i32 %a) {
entry: entry:
...@@ -660,13 +622,11 @@ entry: ...@@ -660,13 +622,11 @@ entry:
; CHECK: mov ; CHECK: mov
; CHECK: shl {{.*}}, 31 ; CHECK: shl {{.*}}, 31
; CHECK: sar {{.*}}, 31 ; CHECK: sar {{.*}}, 31
; CHECK: sar {{.*}}, 31
; ;
; OPTM1-LABEL: sext1To64 ; OPTM1-LABEL: sext1To64
; OPTM1: mov ; OPTM1: mov
; OPTM1: shl {{.*}}, 31 ; OPTM1: shl {{.*}}, 31
; OPTM1: sar {{.*}}, 31 ; OPTM1: sar {{.*}}, 31
; OPTM1: sar {{.*}}, 31
define internal i64 @zext32To64(i32 %a) { define internal i64 @zext32To64(i32 %a) {
entry: entry:
......
; 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
; Tests various aspects of i1 related lowering.
; 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
; Test that xor with true uses immediate 1, not -1.
define internal i32 @testXorTrue(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i1 = xor i1 %arg_i1, true
%result = zext i1 %result_i1 to i32
ret i32 %result
}
; CHECK-LABEL: testXorTrue
; CHECK: xor {{.*}}, 1
; Test that trunc to i1 masks correctly.
define internal i32 @testTrunc(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result = zext i1 %arg_i1 to i32
ret i32 %result
}
; CHECK-LABEL: testTrunc
; CHECK: and {{.*}}, 1
; Test zext to i8.
define internal i32 @testZextI8(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i8 = zext i1 %arg_i1 to i8
%result = zext i8 %result_i8 to i32
ret i32 %result
}
; CHECK-LABEL: testZextI8
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the zext i1 instruction
; CHECK: movzx
; CHECK: and {{.*}}, 1
; Test zext to i16.
define internal i32 @testZextI16(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i16 = zext i1 %arg_i1 to i16
%result = zext i16 %result_i16 to i32
ret i32 %result
}
; CHECK-LABEL: testZextI16
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the zext i1 instruction
; CHECK: movzx
; CHECK: and {{.*}}, 1
; Test zext to i32.
define internal i32 @testZextI32(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i32 = zext i1 %arg_i1 to i32
ret i32 %result_i32
}
; CHECK-LABEL: testZextI32
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the zext i1 instruction
; CHECK: movzx
; CHECK: and {{.*}}, 1
; Test zext to i64.
define internal i64 @testZextI64(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i64 = zext i1 %arg_i1 to i64
ret i64 %result_i64
}
; CHECK-LABEL: testZextI64
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the zext i1 instruction
; CHECK: movzx
; CHECK: and {{.*}}, 1
; CHECK: mov {{.*}}, 0
; Test sext to i8.
define internal i32 @testSextI8(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i8 = sext i1 %arg_i1 to i8
%result = sext i8 %result_i8 to i32
ret i32 %result
}
; CHECK-LABEL: testSextI8
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the sext i1 instruction
; CHECK: shl [[REG:.*]], 7
; CHECK-NEXT: sar [[REG]], 7
; Test sext to i16.
define internal i32 @testSextI16(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i16 = sext i1 %arg_i1 to i16
%result = sext i16 %result_i16 to i32
ret i32 %result
}
; CHECK-LABEL: testSextI16
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the sext i1 instruction
; CHECK: movzx [[REG:.*]],
; CHECK-NEXT: shl [[REG]], 15
; CHECK-NEXT: sar [[REG]], 15
; Test sext to i32.
define internal i32 @testSextI32(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i32 = sext i1 %arg_i1 to i32
ret i32 %result_i32
}
; CHECK-LABEL: testSextI32
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the sext i1 instruction
; CHECK: movzx [[REG:.*]],
; CHECK-NEXT: shl [[REG]], 31
; CHECK-NEXT: sar [[REG]], 31
; Test sext to i64.
define internal i64 @testSextI64(i32 %arg) {
entry:
%arg_i1 = trunc i32 %arg to i1
%result_i64 = sext i1 %arg_i1 to i64
ret i64 %result_i64
}
; CHECK-LABEL: testSextI64
; match the trunc instruction
; CHECK: and {{.*}}, 1
; match the sext i1 instruction
; CHECK: movzx [[REG:.*]],
; CHECK-NEXT: shl [[REG]], 31
; CHECK-NEXT: sar [[REG]], 31
; Test fptosi float to i1.
define internal i32 @testFptosiFloat(float %arg) {
entry:
%arg_i1 = fptosi float %arg to i1
%result = sext i1 %arg_i1 to i32
ret i32 %result
}
; CHECK-LABEL: testFptosiFloat
; CHECK: cvttss2si
; CHECK: and {{.*}}, 1
; CHECK: movzx [[REG:.*]],
; CHECK-NEXT: shl [[REG]], 31
; CHECK-NEXT: sar [[REG]], 31
; Test fptosi double to i1.
define internal i32 @testFptosiDouble(double %arg) {
entry:
%arg_i1 = fptosi double %arg to i1
%result = sext i1 %arg_i1 to i32
ret i32 %result
}
; CHECK-LABEL: testFptosiDouble
; CHECK: cvttsd2si
; CHECK: and {{.*}}, 1
; CHECK: movzx [[REG:.*]],
; CHECK-NEXT: shl [[REG]], 31
; CHECK-NEXT: sar [[REG]], 31
; 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