mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-25 13:27:52 +00:00
Enable (sext x) == C --> x == (trunc C) combine
Extend the existing code which handles this for zext. This makes this more useful for targets with ZeroOrNegativeOne BooleanContent and obsoletes a custom combine SI uses for i1 setcc (sext(i1), 0, setne) since the constant will now be shrunk to i1. llvm-svn: 224691
This commit is contained in:
parent
719eb172c2
commit
92400a8e42
@ -1283,36 +1283,53 @@ TargetLowering::SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
|
||||
}
|
||||
|
||||
// (zext x) == C --> x == (trunc C)
|
||||
if (DCI.isBeforeLegalize() && N0->hasOneUse() &&
|
||||
(Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
|
||||
// (sext x) == C --> x == (trunc C)
|
||||
if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
|
||||
DCI.isBeforeLegalize() && N0->hasOneUse()) {
|
||||
unsigned MinBits = N0.getValueSizeInBits();
|
||||
SDValue PreZExt;
|
||||
SDValue PreExt;
|
||||
bool Signed = false;
|
||||
if (N0->getOpcode() == ISD::ZERO_EXTEND) {
|
||||
// ZExt
|
||||
MinBits = N0->getOperand(0).getValueSizeInBits();
|
||||
PreZExt = N0->getOperand(0);
|
||||
PreExt = N0->getOperand(0);
|
||||
} else if (N0->getOpcode() == ISD::AND) {
|
||||
// DAGCombine turns costly ZExts into ANDs
|
||||
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N0->getOperand(1)))
|
||||
if ((C->getAPIntValue()+1).isPowerOf2()) {
|
||||
MinBits = C->getAPIntValue().countTrailingOnes();
|
||||
PreZExt = N0->getOperand(0);
|
||||
PreExt = N0->getOperand(0);
|
||||
}
|
||||
} else if (N0->getOpcode() == ISD::SIGN_EXTEND) {
|
||||
// SExt
|
||||
MinBits = N0->getOperand(0).getValueSizeInBits();
|
||||
PreExt = N0->getOperand(0);
|
||||
Signed = true;
|
||||
} else if (LoadSDNode *LN0 = dyn_cast<LoadSDNode>(N0)) {
|
||||
// ZEXTLOAD
|
||||
// ZEXTLOAD / SEXTLOAD
|
||||
if (LN0->getExtensionType() == ISD::ZEXTLOAD) {
|
||||
MinBits = LN0->getMemoryVT().getSizeInBits();
|
||||
PreZExt = N0;
|
||||
PreExt = N0;
|
||||
} else if (LN0->getExtensionType() == ISD::SEXTLOAD) {
|
||||
Signed = true;
|
||||
MinBits = LN0->getMemoryVT().getSizeInBits();
|
||||
PreExt = N0;
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out how many bits we need to preserve this constant.
|
||||
unsigned ReqdBits = Signed ?
|
||||
C1.getBitWidth() - C1.getNumSignBits() + 1 :
|
||||
C1.getActiveBits();
|
||||
|
||||
// Make sure we're not losing bits from the constant.
|
||||
if (MinBits > 0 &&
|
||||
MinBits < C1.getBitWidth() && MinBits >= C1.getActiveBits()) {
|
||||
MinBits < C1.getBitWidth() &&
|
||||
MinBits >= ReqdBits) {
|
||||
EVT MinVT = EVT::getIntegerVT(*DAG.getContext(), MinBits);
|
||||
if (isTypeDesirableForOp(ISD::SETCC, MinVT)) {
|
||||
// Will get folded away.
|
||||
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MinVT, PreZExt);
|
||||
SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MinVT, PreExt);
|
||||
SDValue C = DAG.getConstant(C1.trunc(MinBits), MinVT);
|
||||
return DAG.getSetCC(dl, VT, Trunc, C, Cond);
|
||||
}
|
||||
|
@ -1361,29 +1361,10 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N,
|
||||
DAGCombinerInfo &DCI) const {
|
||||
SelectionDAG &DAG = DCI.DAG;
|
||||
SDLoc DL(N);
|
||||
EVT VT = N->getValueType(0);
|
||||
|
||||
switch (N->getOpcode()) {
|
||||
default: return AMDGPUTargetLowering::PerformDAGCombine(N, DCI);
|
||||
case ISD::SETCC: {
|
||||
SDValue Arg0 = N->getOperand(0);
|
||||
SDValue Arg1 = N->getOperand(1);
|
||||
SDValue CC = N->getOperand(2);
|
||||
ConstantSDNode * C = nullptr;
|
||||
ISD::CondCode CCOp = dyn_cast<CondCodeSDNode>(CC)->get();
|
||||
|
||||
// i1 setcc (sext(i1), 0, setne) -> i1 setcc(i1, 0, setne)
|
||||
if (VT == MVT::i1
|
||||
&& Arg0.getOpcode() == ISD::SIGN_EXTEND
|
||||
&& Arg0.getOperand(0).getValueType() == MVT::i1
|
||||
&& (C = dyn_cast<ConstantSDNode>(Arg1))
|
||||
&& C->isNullValue()
|
||||
&& CCOp == ISD::SETNE) {
|
||||
return SimplifySetCC(VT, Arg0.getOperand(0),
|
||||
DAG.getConstant(0, MVT::i1), CCOp, true, DCI, DL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return AMDGPUTargetLowering::PerformDAGCombine(N, DCI);
|
||||
case ISD::FMAXNUM: // TODO: What about fmax_legacy?
|
||||
case ISD::FMINNUM:
|
||||
case AMDGPUISD::SMAX:
|
||||
|
@ -1,15 +1,233 @@
|
||||
; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
|
||||
|
||||
; SI-LABEL: {{^}}sext_bool_icmp_ne:
|
||||
; SI: v_cmp_ne_i32
|
||||
; SI-NEXT: v_cndmask_b32
|
||||
; SI-NOT: v_cmp_ne_i32
|
||||
; SI-NOT: v_cndmask_b32
|
||||
; SI: s_endpgm
|
||||
define void @sext_bool_icmp_ne(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
; FUNC-LABEL: {{^}}sext_bool_icmp_eq_0:
|
||||
; SI-NOT: v_cmp
|
||||
; SI: v_cmp_ne_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT:buffer_store_byte [[RESULT]]
|
||||
; SI-NEXT: s_endpgm
|
||||
|
||||
; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
|
||||
; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
|
||||
define void @sext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp eq i32 %a, %b
|
||||
%ext = sext i1 %icmp0 to i32
|
||||
%icmp1 = icmp eq i32 %ext, 0
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}sext_bool_icmp_ne_0:
|
||||
; SI-NOT: v_cmp
|
||||
; SI: v_cmp_ne_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI-NEXT: s_endpgm
|
||||
|
||||
; EG: SETNE_INT * [[CMP:T[0-9]+]].[[CMPCHAN:[XYZW]]], KC0[2].Z, KC0[2].W
|
||||
; EG: AND_INT T{{[0-9]+.[XYZW]}}, PS, 1
|
||||
define void @sext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp ne i32 %a, %b
|
||||
%ext = sext i1 %icmp0 to i32
|
||||
%icmp1 = icmp ne i32 %ext, 0
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; This really folds away to false
|
||||
; FUNC-LABEL: {{^}}sext_bool_icmp_eq_1:
|
||||
; SI: v_cmp_eq_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
|
||||
; SI-NEXT: v_cmp_eq_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}}
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
|
||||
; SI-NEXT: buffer_store_byte [[TMP]]
|
||||
; SI-NEXT: s_endpgm
|
||||
define void @sext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp eq i32 %a, %b
|
||||
%ext = sext i1 %icmp0 to i32
|
||||
%icmp1 = icmp eq i32 %ext, 1
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; This really folds away to true
|
||||
; FUNC-LABEL: {{^}}sext_bool_icmp_ne_1:
|
||||
; SI: v_cmp_ne_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, -1, vcc
|
||||
; SI-NEXT: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[TMP]], 1{{$}}
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[TMP:v[0-9]+]], 0, 1,
|
||||
; SI-NEXT: buffer_store_byte [[TMP]]
|
||||
; SI-NEXT: s_endpgm
|
||||
define void @sext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp ne i32 %a, %b
|
||||
%ext = sext i1 %icmp0 to i32
|
||||
%icmp1 = icmp ne i32 %ext, 1
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zext_bool_icmp_eq_0:
|
||||
; SI-NOT: v_cmp
|
||||
; SI: v_cmp_ne_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI-NEXT: s_endpgm
|
||||
define void @zext_bool_icmp_eq_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp eq i32 %a, %b
|
||||
%ext = zext i1 %icmp0 to i32
|
||||
%icmp1 = icmp eq i32 %ext, 0
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zext_bool_icmp_ne_0:
|
||||
; SI-NOT: v_cmp
|
||||
; SI: v_cmp_ne_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI-NEXT: s_endpgm
|
||||
define void @zext_bool_icmp_ne_0(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp ne i32 %a, %b
|
||||
%ext = zext i1 %icmp0 to i32
|
||||
%icmp1 = icmp ne i32 %ext, 0
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zext_bool_icmp_eq_1:
|
||||
; SI-NOT: v_cmp
|
||||
; SI: v_cmp_eq_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI-NEXT: s_endpgm
|
||||
define void @zext_bool_icmp_eq_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp eq i32 %a, %b
|
||||
%ext = zext i1 %icmp0 to i32
|
||||
%icmp1 = icmp eq i32 %ext, 1
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zext_bool_icmp_ne_1:
|
||||
; SI-NOT: v_cmp
|
||||
; SI: v_cmp_eq_i32_e32 vcc,
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @zext_bool_icmp_ne_1(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp ne i32 %a, %b
|
||||
%ext = zext i1 %icmp0 to i32
|
||||
%icmp1 = icmp ne i32 %ext, 1
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}sext_bool_icmp_ne_k:
|
||||
; SI-DAG: s_load_dword [[A:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xb
|
||||
; SI-DAG: s_load_dword [[B:s[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0xc
|
||||
; SI: v_mov_b32_e32 [[VB:v[0-9]+]], [[B]]
|
||||
; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[VB]], 2{{$}}
|
||||
; SI: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
|
||||
; SI: buffer_store_byte
|
||||
; SI: s_endpgm
|
||||
define void @sext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp ne i32 %a, %b
|
||||
%ext = sext i1 %icmp0 to i32
|
||||
%icmp1 = icmp ne i32 %ext, 2
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}cmp_zext_k_i8max:
|
||||
; SI: buffer_load_ubyte [[B:v[0-9]+]], s{{\[[0-9]+:[0-9]+\]}}, 0 offset:44
|
||||
; SI: v_mov_b32_e32 [[K255:v[0-9]+]], 0xff{{$}}
|
||||
; SI: v_cmp_ne_i32_e32 vcc, [[B]], [[K255]]
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI: s_endpgm
|
||||
define void @cmp_zext_k_i8max(i1 addrspace(1)* %out, i8 %b) nounwind {
|
||||
%b.ext = zext i8 %b to i32
|
||||
%icmp0 = icmp ne i32 %b.ext, 255
|
||||
store i1 %icmp0, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}cmp_sext_k_neg1:
|
||||
; SI: buffer_load_sbyte [[B:v[0-9]+]]
|
||||
; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}}
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI: s_endpgm
|
||||
define void @cmp_sext_k_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %b.ptr) nounwind {
|
||||
%b = load i8 addrspace(1)* %b.ptr
|
||||
%b.ext = sext i8 %b to i32
|
||||
%icmp0 = icmp ne i32 %b.ext, -1
|
||||
store i1 %icmp0, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_sext_arg:
|
||||
; SI: s_load_dword [[B:s[0-9]+]]
|
||||
; SI: v_cmp_ne_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[B]], -1{{$}}
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI: s_endpgm
|
||||
define void @cmp_sext_k_neg1_i8_sext_arg(i1 addrspace(1)* %out, i8 signext %b) nounwind {
|
||||
%b.ext = sext i8 %b to i32
|
||||
%icmp0 = icmp ne i32 %b.ext, -1
|
||||
store i1 %icmp0, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FIXME: This ends up doing a buffer_load_ubyte, and and compare to
|
||||
; 255. Seems to be because of ordering problems when not allowing load widths to be reduced.
|
||||
; Should do a buffer_load_sbyte and compare with -1
|
||||
|
||||
; FUNC-LABEL: {{^}}cmp_sext_k_neg1_i8_arg:
|
||||
; SI-DAG: buffer_load_ubyte [[B:v[0-9]+]]
|
||||
; SI-DAG: v_mov_b32_e32 [[K:v[0-9]+]], 0xff{{$}}
|
||||
; SI: v_cmp_ne_i32_e32 vcc, [[B]], [[K]]{{$}}
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, vcc
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI: s_endpgm
|
||||
define void @cmp_sext_k_neg1_i8_arg(i1 addrspace(1)* %out, i8 %b) nounwind {
|
||||
%b.ext = sext i8 %b to i32
|
||||
%icmp0 = icmp ne i32 %b.ext, -1
|
||||
store i1 %icmp0, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}cmp_zext_k_neg1:
|
||||
; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI: s_endpgm
|
||||
define void @cmp_zext_k_neg1(i1 addrspace(1)* %out, i8 %b) nounwind {
|
||||
%b.ext = zext i8 %b to i32
|
||||
%icmp0 = icmp ne i32 %b.ext, -1
|
||||
store i1 %icmp0, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zext_bool_icmp_ne_k:
|
||||
; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI-NEXT: s_endpgm
|
||||
define void @zext_bool_icmp_ne_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp ne i32 %a, %b
|
||||
%ext = zext i1 %icmp0 to i32
|
||||
%icmp1 = icmp ne i32 %ext, 2
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zext_bool_icmp_eq_k:
|
||||
; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
; SI-NEXT: s_endpgm
|
||||
define void @zext_bool_icmp_eq_k(i1 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
|
||||
%icmp0 = icmp ne i32 %a, %b
|
||||
%ext = zext i1 %icmp0 to i32
|
||||
%icmp1 = icmp eq i32 %ext, 2
|
||||
store i1 %icmp1, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
169
test/CodeGen/R600/trunc-cmp-constant.ll
Normal file
169
test/CodeGen/R600/trunc-cmp-constant.ll
Normal file
@ -0,0 +1,169 @@
|
||||
; RUN: llc -march=r600 -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
|
||||
|
||||
; FUNC-LABEL {{^}}sextload_i1_to_i32_trunc_cmp_eq_0:
|
||||
; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
|
||||
; SI: v_cmp_eq_i32_e64 [[CMP:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}}
|
||||
; SI: s_xor_b64 s{{\[[0-9]+:[0-9]+\]}}, s{{\[[0-9]+:[0-9]+\]}}, -1{{$}}
|
||||
; SI: v_cndmask_b32_e64
|
||||
; SI: buffer_store_byte
|
||||
define void @sextload_i1_to_i32_trunc_cmp_eq_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = sext i1 %load to i32
|
||||
%cmp = icmp eq i32 %ext, 0
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FIXME: The negate should be inverting the compare.
|
||||
; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_eq_0:
|
||||
; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
|
||||
; SI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}}
|
||||
; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], [[CMP0]], -1
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[NEG]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @zextload_i1_to_i32_trunc_cmp_eq_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = zext i1 %load to i32
|
||||
%cmp = icmp eq i32 %ext, 0
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_eq_1:
|
||||
; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @sextload_i1_to_i32_trunc_cmp_eq_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = sext i1 %load to i32
|
||||
%cmp = icmp eq i32 %ext, 1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_eq_1:
|
||||
; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_and_b32_e32 [[RESULT:v[0-9]+]], 1, [[LOAD]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @zextload_i1_to_i32_trunc_cmp_eq_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = zext i1 %load to i32
|
||||
%cmp = icmp eq i32 %ext, 1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_eq_neg1:
|
||||
; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_and_b32_e32 [[RESULT:v[0-9]+]], 1, [[LOAD]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @sextload_i1_to_i32_trunc_cmp_eq_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = sext i1 %load to i32
|
||||
%cmp = icmp eq i32 %ext, -1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_eq_neg1:
|
||||
; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 0{{$}}
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @zextload_i1_to_i32_trunc_cmp_eq_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = zext i1 %load to i32
|
||||
%cmp = icmp eq i32 %ext, -1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; FUNC-LABEL {{^}}sextload_i1_to_i32_trunc_cmp_ne_0:
|
||||
; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @sextload_i1_to_i32_trunc_cmp_ne_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = sext i1 %load to i32
|
||||
%cmp = icmp ne i32 %ext, 0
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_ne_0:
|
||||
; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @zextload_i1_to_i32_trunc_cmp_ne_0(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = zext i1 %load to i32
|
||||
%cmp = icmp ne i32 %ext, 0
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_ne_1:
|
||||
; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @sextload_i1_to_i32_trunc_cmp_ne_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = sext i1 %load to i32
|
||||
%cmp = icmp ne i32 %ext, 1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_ne_1:
|
||||
; SI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
|
||||
; SI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 1{{$}}
|
||||
; SI-NEXT: s_xor_b64 [[NEG:s\[[0-9]+:[0-9]+\]]], [[CMP0]], -1
|
||||
; SI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[NEG]]
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @zextload_i1_to_i32_trunc_cmp_ne_1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = zext i1 %load to i32
|
||||
%cmp = icmp ne i32 %ext, 1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FIXME: This should be one compare.
|
||||
; FUNC-LABEL: {{^}}sextload_i1_to_i32_trunc_cmp_ne_neg1:
|
||||
; XSI: buffer_load_ubyte [[LOAD:v[0-9]+]]
|
||||
; XSI: v_and_b32_e32 [[TMP:v[0-9]+]], 1, [[LOAD]]
|
||||
; XSI: v_cmp_eq_i32_e64 [[CMP0:s\[[0-9]+:[0-9]+\]]], [[TMP]], 0{{$}}
|
||||
; XSI-NEXT: v_cndmask_b32_e64 [[RESULT:v[0-9]+]], 0, 1, [[CMP0]]
|
||||
; XSI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @sextload_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = sext i1 %load to i32
|
||||
%cmp = icmp ne i32 %ext, -1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}zextload_i1_to_i32_trunc_cmp_ne_neg1:
|
||||
; SI: v_mov_b32_e32 [[RESULT:v[0-9]+]], 1{{$}}
|
||||
; SI-NEXT: buffer_store_byte [[RESULT]]
|
||||
define void @zextload_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i1 addrspace(1)* %in) nounwind {
|
||||
%load = load i1 addrspace(1)* %in
|
||||
%ext = zext i1 %load to i32
|
||||
%cmp = icmp ne i32 %ext, -1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
||||
|
||||
; FUNC-LABEL: {{^}}masked_load_i1_to_i32_trunc_cmp_ne_neg1:
|
||||
; SI: buffer_load_sbyte [[LOAD:v[0-9]+]]
|
||||
; SI: v_cmp_ne_i32_e64 {{s\[[0-9]+:[0-9]+\]}}, [[LOAD]], -1{{$}}
|
||||
; SI-NEXT: v_cndmask_b32_e64
|
||||
; SI-NEXT: buffer_store_byte
|
||||
define void @masked_load_i1_to_i32_trunc_cmp_ne_neg1(i1 addrspace(1)* %out, i8 addrspace(1)* %in) nounwind {
|
||||
%load = load i8 addrspace(1)* %in
|
||||
%masked = and i8 %load, 255
|
||||
%ext = sext i8 %masked to i32
|
||||
%cmp = icmp ne i32 %ext, -1
|
||||
store i1 %cmp, i1 addrspace(1)* %out
|
||||
ret void
|
||||
}
|
@ -89,3 +89,151 @@ if.end:
|
||||
; CHECK-NOT: cmpl $1,{{.*}}x+4
|
||||
; CHECK: ret
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test2_1:
|
||||
; CHECK: movzbl
|
||||
; CHECK: cmpl $256
|
||||
; CHECK: jne
|
||||
define void @test2_1(i32 %X) nounwind minsize {
|
||||
entry:
|
||||
%and = and i32 %X, 255
|
||||
%cmp = icmp eq i32 %and, 256
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_1:
|
||||
; CHECK: cmpb $1, %{{dil|cl}}
|
||||
define void @test_sext_i8_icmp_1(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, 1
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_47:
|
||||
; CHECK: cmpb $47, %{{dil|cl}}
|
||||
define void @test_sext_i8_icmp_47(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, 47
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_127:
|
||||
; CHECK: cmpb $127, %{{dil|cl}}
|
||||
define void @test_sext_i8_icmp_127(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, 127
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_neg1:
|
||||
; CHECK: cmpb $-1, %{{dil|cl}}
|
||||
define void @test_sext_i8_icmp_neg1(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, -1
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_neg2:
|
||||
; CHECK: cmpb $-2, %{{dil|cl}}
|
||||
define void @test_sext_i8_icmp_neg2(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, -2
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_neg127:
|
||||
; CHECK: cmpb $-127, %{{dil|cl}}
|
||||
define void @test_sext_i8_icmp_neg127(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, -127
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_neg128:
|
||||
; CHECK: cmpb $-128, %{{dil|cl}}
|
||||
define void @test_sext_i8_icmp_neg128(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, -128
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: test_sext_i8_icmp_255:
|
||||
; CHECK: movb $1,
|
||||
; CHECK: testb
|
||||
; CHECK: jne
|
||||
define void @test_sext_i8_icmp_255(i8 %x) nounwind minsize {
|
||||
entry:
|
||||
%sext = sext i8 %x to i32
|
||||
%cmp = icmp eq i32 %sext, 255
|
||||
br i1 %cmp, label %if.then, label %if.end
|
||||
|
||||
if.then:
|
||||
tail call void @bar() nounwind
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
ret void
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user