forked from OSchip/llvm-project
[x86] fix usage of stale operands when lowering select
I noticed this problem as part of the ongoing attempt to canonicalize min/max ops in IR. The debug output shows nodes like this: t4: i32 = xor t2, Constant:i32<-1> t21: i8 = setcc t4, Constant:i32<0>, setlt:ch t14: i32 = select t21, t4, Constant:i32<-1> And because the select is holding onto the t4 (xor) node while EmitTest creates a new x86-specific xor node, the lowering results in: t4: i32 = xor t2, Constant:i32<-1> t25: i32,i32 = X86ISD::XOR t2, Constant:i32<-1> t28: i32,glue = X86ISD::CMOV Constant:i32<-1>, t4, Constant:i8<15>, t25:1 Differential Revision: https://reviews.llvm.org/D28374 llvm-svn: 291392
This commit is contained in:
parent
9c58950eeb
commit
bf51c8a975
|
@ -16991,9 +16991,16 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) const {
|
|||
return DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, newSelect, zeroConst);
|
||||
}
|
||||
|
||||
if (Cond.getOpcode() == ISD::SETCC)
|
||||
if (SDValue NewCond = LowerSETCC(Cond, DAG))
|
||||
if (Cond.getOpcode() == ISD::SETCC) {
|
||||
if (SDValue NewCond = LowerSETCC(Cond, DAG)) {
|
||||
Cond = NewCond;
|
||||
// If the condition was updated, it's possible that the operands of the
|
||||
// select were also updated (for example, EmitTest has a RAUW). Refresh
|
||||
// the local references to the select operands in case they got stale.
|
||||
Op1 = Op.getOperand(1);
|
||||
Op2 = Op.getOperand(2);
|
||||
}
|
||||
}
|
||||
|
||||
// (select (x == 0), -1, y) -> (sign_bit (x - 1)) | y
|
||||
// (select (x == 0), y, -1) -> ~(sign_bit (x - 1)) | y
|
||||
|
|
|
@ -157,16 +157,12 @@ define i8 @test7(i1 inreg %c, i8 inreg %a, i8 inreg %b) nounwind {
|
|||
ret i8 %d
|
||||
}
|
||||
|
||||
; FIXME: The 'not' is redundant.
|
||||
|
||||
define i32 @smin(i32 %x) {
|
||||
; CHECK-LABEL: smin:
|
||||
; CHECK: ## BB#0:
|
||||
; CHECK-NEXT: movl %edi, %ecx
|
||||
; CHECK-NEXT: notl %ecx
|
||||
; CHECK-NEXT: xorl $-1, %edi
|
||||
; CHECK-NEXT: movl $-1, %eax
|
||||
; CHECK-NEXT: cmovsl %ecx, %eax
|
||||
; CHECK-NEXT: cmovsl %edi, %eax
|
||||
; CHECK-NEXT: retq
|
||||
%not_x = xor i32 %x, -1
|
||||
%1 = icmp slt i32 %not_x, -1
|
||||
|
|
Loading…
Reference in New Issue