[DAGCombine] foldBinOpIntoSelect can fail to constant fold in some cases.

For example, float operations may fail to constant fold under certain circumstances (inf/nan/denormal creation etc.)

Reduced from oss-fuzz #4802 test case

llvm-svn: 321488
This commit is contained in:
Simon Pilgrim 2017-12-27 11:36:18 +00:00
parent a09663a5c1
commit 6fad3cbc66
2 changed files with 43 additions and 6 deletions

View File

@ -1922,14 +1922,16 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) {
EVT VT = Sel.getValueType();
SDLoc DL(Sel);
SDValue NewCT = DAG.getNode(BinOpcode, DL, VT, CT, C1);
assert((NewCT.isUndef() || isConstantOrConstantVector(NewCT) ||
isConstantFPBuildVectorOrConstantFP(NewCT)) &&
"Failed to constant fold a binop with constant operands");
if (!NewCT.isUndef() &&
!isConstantOrConstantVector(NewCT, true) &&
!isConstantFPBuildVectorOrConstantFP(NewCT))
return SDValue();
SDValue NewCF = DAG.getNode(BinOpcode, DL, VT, CF, C1);
assert((NewCF.isUndef() || isConstantOrConstantVector(NewCF) ||
isConstantFPBuildVectorOrConstantFP(NewCF)) &&
"Failed to constant fold a binop with constant operands");
if (!NewCF.isUndef() &&
!isConstantOrConstantVector(NewCF, true) &&
!isConstantFPBuildVectorOrConstantFP(NewCF))
return SDValue();
return DAG.getSelect(DL, VT, Sel.getOperand(0), NewCT, NewCF);
}

View File

@ -95,6 +95,41 @@ define double @div3_arcp(double %x, double %y, double %z) {
ret double %ret
}
define float @div_select_constant_fold(i1 zeroext %arg) {
; CHECK-LABEL: div_select_constant_fold:
; CHECK: # %bb.0:
; CHECK-NEXT: testl %edi, %edi
; CHECK-NEXT: jne .LBB6_1
; CHECK-NEXT: # %bb.2:
; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB6_1:
; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-NEXT: retq
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
%B2 = fdiv float %tmp, 1.000000e+00
ret float %B2
}
define float @div_select_constant_fold_zero(i1 zeroext %arg) {
; CHECK-LABEL: div_select_constant_fold_zero:
; CHECK: # %bb.0:
; CHECK-NEXT: testl %edi, %edi
; CHECK-NEXT: jne .LBB7_1
; CHECK-NEXT: # %bb.2:
; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-NEXT: jmp .LBB7_3
; CHECK-NEXT: .LBB7_1:
; CHECK-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero
; CHECK-NEXT: .LBB7_3:
; CHECK-NEXT: xorps %xmm1, %xmm1
; CHECK-NEXT: divss %xmm1, %xmm0
; CHECK-NEXT: retq
%tmp = select i1 %arg, float 5.000000e+00, float 6.000000e+00
%B2 = fdiv float %tmp, 0.000000e+00
ret float %B2
}
define void @PR24141() {
; CHECK-LABEL: PR24141:
; CHECK: callq