From: Sanjay Patel Date: Thu, 2 Mar 2017 17:18:56 +0000 (+0000) Subject: [DAGCombiner] avoid assertion when folding binops with opaque constants X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d541a8113c21b3ce4d5fdb304c16355140361383;p=llvm [DAGCombiner] avoid assertion when folding binops with opaque constants This bug was introduced with: https://reviews.llvm.org/rL296699 There may be a way to loosen the restriction, but for now just bail out on any opaque constant. The tests show that opacity is target-specific. This goes back to cost calculations in ConstantHoisting based on TTI->getIntImmCost(). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296768 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d8c14da15dc..2f6a26d319f 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1761,8 +1761,9 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) { BinOpcode == ISD::FDIV || BinOpcode == ISD::FREM) && "Unexpected binary operator"); + // Bail out if any constants are opaque because we can't constant fold those. SDValue C1 = BO->getOperand(1); - if (!isConstantOrConstantVector(C1) && + if (!isConstantOrConstantVector(C1, true) && !isConstantFPBuildVectorOrConstantFP(C1)) return SDValue(); @@ -1774,12 +1775,12 @@ SDValue DAGCombiner::foldBinOpIntoSelect(SDNode *BO) { return SDValue(); SDValue CT = Sel.getOperand(1); - if (!isConstantOrConstantVector(CT) && + if (!isConstantOrConstantVector(CT, true) && !isConstantFPBuildVectorOrConstantFP(CT)) return SDValue(); SDValue CF = Sel.getOperand(2); - if (!isConstantOrConstantVector(CF) && + if (!isConstantOrConstantVector(CF, true) && !isConstantFPBuildVectorOrConstantFP(CF)) return SDValue(); diff --git a/test/CodeGen/ARM/select_const.ll b/test/CodeGen/ARM/select_const.ll index 52d9af0399c..48fe572bf8a 100644 --- a/test/CodeGen/ARM/select_const.ll +++ b/test/CodeGen/ARM/select_const.ll @@ -273,3 +273,54 @@ define i32 @select_C1_C2_signext(i1 signext %cond) { ret i32 %sel } +; 4295032833 = 0x100010001. +; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select. + +define i64 @opaque_constant1(i1 %cond, i64 %x) { +; CHECK-LABEL: opaque_constant1: +; CHECK: @ BB#0: +; CHECK-NEXT: .save {r4, lr} +; CHECK-NEXT: push {r4, lr} +; CHECK-NEXT: ands r12, r0, #1 +; CHECK-NEXT: mov lr, #1 +; CHECK-NEXT: mov r0, #23 +; CHECK-NEXT: eor r3, r3, #1 +; CHECK-NEXT: orr lr, lr, #65536 +; CHECK-NEXT: mvnne r0, #3 +; CHECK-NEXT: movne r12, #1 +; CHECK-NEXT: and r4, r0, lr +; CHECK-NEXT: eor r2, r2, lr +; CHECK-NEXT: subs r0, r4, #1 +; CHECK-NEXT: sbc r1, r12, #0 +; CHECK-NEXT: orrs r2, r2, r3 +; CHECK-NEXT: movne r0, r4 +; CHECK-NEXT: movne r1, r12 +; CHECK-NEXT: pop {r4, lr} +; CHECK-NEXT: mov pc, lr + %sel = select i1 %cond, i64 -4, i64 23 + %bo = and i64 %sel, 4295032833 ; 0x100010001 + %cmp = icmp eq i64 %x, 4295032833 + %sext = sext i1 %cmp to i64 + %add = add i64 %bo, %sext + ret i64 %add +} + +; 65537 == 0x10001. +; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select. + +define i64 @opaque_constant2(i1 %cond, i64 %x) { +; CHECK-LABEL: opaque_constant2: +; CHECK: @ BB#0: +; CHECK-NEXT: mov r1, #1 +; CHECK-NEXT: tst r0, #1 +; CHECK-NEXT: orr r1, r1, #65536 +; CHECK-NEXT: mov r0, r1 +; CHECK-NEXT: moveq r0, #23 +; CHECK-NEXT: and r0, r0, r1 +; CHECK-NEXT: mov r1, #0 +; CHECK-NEXT: mov pc, lr + %sel = select i1 %cond, i64 65537, i64 23 + %bo = and i64 %sel, 65537 + ret i64 %bo +} + diff --git a/test/CodeGen/X86/select_const.ll b/test/CodeGen/X86/select_const.ll index c19060e6bcf..716ee70d926 100644 --- a/test/CodeGen/X86/select_const.ll +++ b/test/CodeGen/X86/select_const.ll @@ -291,3 +291,29 @@ define <2 x double> @sel_constants_fmul_constant_vec(i1 %cond) { %bo = fmul <2 x double> %sel, ret <2 x double> %bo } + +; 4294967297 = 0x100000001. +; This becomes an opaque constant via ConstantHoisting, so we don't fold it into the select. + +define i64 @opaque_constant(i1 %cond, i64 %x) { +; CHECK-LABEL: opaque_constant: +; CHECK: # BB#0: +; CHECK-NEXT: testb $1, %dil +; CHECK-NEXT: movl $23, %ecx +; CHECK-NEXT: movq $-4, %rax +; CHECK-NEXT: cmoveq %rcx, %rax +; CHECK-NEXT: movabsq $4294967297, %rcx # imm = 0x100000001 +; CHECK-NEXT: andq %rcx, %rax +; CHECK-NEXT: xorl %edx, %edx +; CHECK-NEXT: cmpq %rcx, %rsi +; CHECK-NEXT: sete %dl +; CHECK-NEXT: subq %rdx, %rax +; CHECK-NEXT: retq + %sel = select i1 %cond, i64 -4, i64 23 + %bo = and i64 %sel, 4294967297 + %cmp = icmp eq i64 %x, 4294967297 + %sext = sext i1 %cmp to i64 + %add = add i64 %bo, %sext + ret i64 %add +} +