Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1877,16 +1877,16 @@ 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, true) && - !isConstantFPBuildVectorOrConstantFP(C1)) - return SDValue(); - // Don't do this unless the old select is going away. We want to eliminate the // binary operator, not replace a binop with a select. // TODO: Handle ISD::SELECT_CC. + unsigned SelOpNo = 0; SDValue Sel = BO->getOperand(0); + if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse()) { + SelOpNo = 1; + Sel = BO->getOperand(1); + } + if (Sel.getOpcode() != ISD::SELECT || !Sel.hasOneUse()) return SDValue(); @@ -1900,18 +1900,36 @@ !isConstantFPBuildVectorOrConstantFP(CF)) return SDValue(); + // Bail out if any constants are opaque because we can't constant fold those. + SDValue CBO = BO->getOperand(SelOpNo ^ 1); + if (!isConstantOrConstantVector(CBO, true) && + !isConstantFPBuildVectorOrConstantFP(CBO)) + return SDValue(); + + EVT VT = Sel.getValueType(); + + // In case of shift value and shift amount may have different VT. For instance + // on x86 shift amount is i8 regardles of LHS type. Bail out if we have + // swapped operands and value types do not match. NB: x86 is fine if operands + // are not swapped with shift amount VT being not bigger than shifted value. + // TODO: that is possible to check for a shift operation, correct VTs and + // still perform optimization on x86 if needed. + if (SelOpNo && VT != CBO.getValueType()) + return SDValue(); + // We have a select-of-constants followed by a binary operator with a // constant. Eliminate the binop by pulling the constant math into the select. - // Example: add (select Cond, CT, CF), C1 --> select Cond, CT + C1, CF + C1 - EVT VT = Sel.getValueType(); + // Example: add (select Cond, CT, CF), CBO --> select Cond, CT + CBO, CF + CBO SDLoc DL(Sel); - SDValue NewCT = DAG.getNode(BinOpcode, DL, VT, CT, C1); + SDValue NewCT = SelOpNo ? DAG.getNode(BinOpcode, DL, VT, CBO, CT) + : DAG.getNode(BinOpcode, DL, VT, CT, CBO); if (!NewCT.isUndef() && !isConstantOrConstantVector(NewCT, true) && !isConstantFPBuildVectorOrConstantFP(NewCT)) return SDValue(); - SDValue NewCF = DAG.getNode(BinOpcode, DL, VT, CF, C1); + SDValue NewCF = SelOpNo ? DAG.getNode(BinOpcode, DL, VT, CBO, CF) + : DAG.getNode(BinOpcode, DL, VT, CF, CBO); if (!NewCF.isUndef() && !isConstantOrConstantVector(NewCF, true) && !isConstantFPBuildVectorOrConstantFP(NewCF)) Index: test/CodeGen/AMDGPU/dagcombine-select.ll =================================================================== --- /dev/null +++ test/CodeGen/AMDGPU/dagcombine-select.ll @@ -0,0 +1,100 @@ +; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN %s + +; GCN-LABEL: {{^}}sel_constants_sub_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 2, 9, +define amdgpu_kernel void @sel_constants_sub_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 -4, i32 3 + %bo = sub i32 5, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}sdiv_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 5, 0, +define amdgpu_kernel void @sdiv_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 121, i32 23 + %bo = sdiv i32 120, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}udiv_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 5, 0, +define amdgpu_kernel void @udiv_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 -4, i32 23 + %bo = udiv i32 120, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}srem_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 3, 33, +define amdgpu_kernel void @srem_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 34, i32 15 + %bo = srem i32 33, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}urem_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 3, 33, +define amdgpu_kernel void @urem_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 34, i32 15 + %bo = urem i32 33, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}shl_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 8, 4, +define amdgpu_kernel void @shl_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 2, i32 3 + %bo = shl i32 1, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}lshr_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 8, 16, +define amdgpu_kernel void @lshr_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 2, i32 3 + %bo = lshr i32 64, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}ashr_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 8, 32, +define amdgpu_kernel void @ashr_constant_sel_constants(i32 addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, i32 2, i32 3 + %bo = ashr i32 128, %sel + store i32 %bo, i32 addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}fsub_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, -4.0, 1.0, +define amdgpu_kernel void @fsub_constant_sel_constants(float addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, float -2.0, float 3.0 + %bo = fsub float -1.0, %sel + store float %bo, float addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}fdiv_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 4.0, -2.0, +define amdgpu_kernel void @fdiv_constant_sel_constants(float addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, float -4.0, float 2.0 + %bo = fdiv float 8.0, %sel + store float %bo, float addrspace(1)* %p, align 4 + ret void +} + +; GCN-LABEL: {{^}}frem_constant_sel_constants: +; v_cndmask_b32_e64 v{{[0-9]+}}, 2.0, 1.0, +define amdgpu_kernel void @frem_constant_sel_constants(float addrspace(1)* %p, i1 %cond) { + %sel = select i1 %cond, float -4.0, float 3.0 + %bo = frem float 5.0, %sel + store float %bo, float addrspace(1)* %p, align 4 + ret void +} Index: test/CodeGen/PowerPC/select_const.ll =================================================================== --- test/CodeGen/PowerPC/select_const.ll +++ test/CodeGen/PowerPC/select_const.ll @@ -404,23 +404,20 @@ ; ISEL-LABEL: sel_constants_sub_constant_sel_constants: ; ISEL: # %bb.0: ; ISEL-NEXT: andi. 3, 3, 1 -; ISEL-NEXT: li 4, -4 -; ISEL-NEXT: li 3, 3 +; ISEL-NEXT: li 4, 9 +; ISEL-NEXT: li 3, 2 ; ISEL-NEXT: isel 3, 4, 3, 1 -; ISEL-NEXT: subfic 3, 3, 5 ; ISEL-NEXT: blr ; ; NO_ISEL-LABEL: sel_constants_sub_constant_sel_constants: ; NO_ISEL: # %bb.0: ; NO_ISEL-NEXT: andi. 3, 3, 1 -; NO_ISEL-NEXT: li 4, -4 -; NO_ISEL-NEXT: li 3, 3 +; NO_ISEL-NEXT: li 4, 9 +; NO_ISEL-NEXT: li 3, 2 ; NO_ISEL-NEXT: bc 12, 1, .LBB23_1 -; NO_ISEL-NEXT: b .LBB23_2 +; NO_ISEL-NEXT: blr ; NO_ISEL-NEXT: .LBB23_1: ; NO_ISEL-NEXT: addi 3, 4, 0 -; NO_ISEL-NEXT: .LBB23_2: -; NO_ISEL-NEXT: subfic 3, 3, 5 ; NO_ISEL-NEXT: blr %sel = select i1 %cond, i8 -4, i8 3 %bo = sub i8 5, %sel @@ -480,25 +477,18 @@ ; ISEL-LABEL: sdiv_constant_sel_constants: ; ISEL: # %bb.0: ; ISEL-NEXT: andi. 3, 3, 1 -; ISEL-NEXT: li 4, 121 -; ISEL-NEXT: li 12, 120 -; ISEL-NEXT: li 3, 23 -; ISEL-NEXT: isel 3, 4, 3, 1 -; ISEL-NEXT: divwu 3, 12, 3 +; ISEL-NEXT: li 3, 5 +; ISEL-NEXT: isel 3, 0, 3, 1 ; ISEL-NEXT: blr ; ; NO_ISEL-LABEL: sdiv_constant_sel_constants: ; NO_ISEL: # %bb.0: ; NO_ISEL-NEXT: andi. 3, 3, 1 -; NO_ISEL-NEXT: li 4, 121 -; NO_ISEL-NEXT: li 12, 120 -; NO_ISEL-NEXT: li 3, 23 +; NO_ISEL-NEXT: li 3, 5 ; NO_ISEL-NEXT: bc 12, 1, .LBB26_1 -; NO_ISEL-NEXT: b .LBB26_2 +; NO_ISEL-NEXT: blr ; NO_ISEL-NEXT: .LBB26_1: -; NO_ISEL-NEXT: addi 3, 4, 0 -; NO_ISEL-NEXT: .LBB26_2: -; NO_ISEL-NEXT: divwu 3, 12, 3 +; NO_ISEL-NEXT: addi 3, 0, 0 ; NO_ISEL-NEXT: blr %sel = select i1 %cond, i8 121, i8 23 %bo = sdiv i8 120, %sel @@ -533,25 +523,18 @@ ; ISEL-LABEL: udiv_constant_sel_constants: ; ISEL: # %bb.0: ; ISEL-NEXT: andi. 3, 3, 1 -; ISEL-NEXT: li 4, 252 -; ISEL-NEXT: li 12, 120 -; ISEL-NEXT: li 3, 23 -; ISEL-NEXT: isel 3, 4, 3, 1 -; ISEL-NEXT: divwu 3, 12, 3 +; ISEL-NEXT: li 3, 5 +; ISEL-NEXT: isel 3, 0, 3, 1 ; ISEL-NEXT: blr ; ; NO_ISEL-LABEL: udiv_constant_sel_constants: ; NO_ISEL: # %bb.0: ; NO_ISEL-NEXT: andi. 3, 3, 1 -; NO_ISEL-NEXT: li 4, 252 -; NO_ISEL-NEXT: li 12, 120 -; NO_ISEL-NEXT: li 3, 23 +; NO_ISEL-NEXT: li 3, 5 ; NO_ISEL-NEXT: bc 12, 1, .LBB28_1 -; NO_ISEL-NEXT: b .LBB28_2 +; NO_ISEL-NEXT: blr ; NO_ISEL-NEXT: .LBB28_1: -; NO_ISEL-NEXT: addi 3, 4, 0 -; NO_ISEL-NEXT: .LBB28_2: -; NO_ISEL-NEXT: divwu 3, 12, 3 +; NO_ISEL-NEXT: addi 3, 0, 0 ; NO_ISEL-NEXT: blr %sel = select i1 %cond, i8 -4, i8 23 %bo = udiv i8 120, %sel @@ -589,29 +572,20 @@ ; ISEL-LABEL: srem_constant_sel_constants: ; ISEL: # %bb.0: ; ISEL-NEXT: andi. 3, 3, 1 -; ISEL-NEXT: li 4, 121 -; ISEL-NEXT: li 12, 120 -; ISEL-NEXT: li 3, 23 +; ISEL-NEXT: li 4, 120 +; ISEL-NEXT: li 3, 5 ; ISEL-NEXT: isel 3, 4, 3, 1 -; ISEL-NEXT: divwu 4, 12, 3 -; ISEL-NEXT: mullw 3, 4, 3 -; ISEL-NEXT: subfic 3, 3, 120 ; ISEL-NEXT: blr ; ; NO_ISEL-LABEL: srem_constant_sel_constants: ; NO_ISEL: # %bb.0: ; NO_ISEL-NEXT: andi. 3, 3, 1 -; NO_ISEL-NEXT: li 4, 121 -; NO_ISEL-NEXT: li 12, 120 -; NO_ISEL-NEXT: li 3, 23 +; NO_ISEL-NEXT: li 4, 120 +; NO_ISEL-NEXT: li 3, 5 ; NO_ISEL-NEXT: bc 12, 1, .LBB30_1 -; NO_ISEL-NEXT: b .LBB30_2 +; NO_ISEL-NEXT: blr ; NO_ISEL-NEXT: .LBB30_1: ; NO_ISEL-NEXT: addi 3, 4, 0 -; NO_ISEL-NEXT: .LBB30_2: -; NO_ISEL-NEXT: divwu 4, 12, 3 -; NO_ISEL-NEXT: mullw 3, 4, 3 -; NO_ISEL-NEXT: subfic 3, 3, 120 ; NO_ISEL-NEXT: blr %sel = select i1 %cond, i8 121, i8 23 %bo = srem i8 120, %sel @@ -633,29 +607,20 @@ ; ISEL-LABEL: urem_constant_sel_constants: ; ISEL: # %bb.0: ; ISEL-NEXT: andi. 3, 3, 1 -; ISEL-NEXT: li 4, 252 -; ISEL-NEXT: li 12, 120 -; ISEL-NEXT: li 3, 23 +; ISEL-NEXT: li 4, 120 +; ISEL-NEXT: li 3, 5 ; ISEL-NEXT: isel 3, 4, 3, 1 -; ISEL-NEXT: divwu 4, 12, 3 -; ISEL-NEXT: mullw 3, 4, 3 -; ISEL-NEXT: subfic 3, 3, 120 ; ISEL-NEXT: blr ; ; NO_ISEL-LABEL: urem_constant_sel_constants: ; NO_ISEL: # %bb.0: ; NO_ISEL-NEXT: andi. 3, 3, 1 -; NO_ISEL-NEXT: li 4, 252 -; NO_ISEL-NEXT: li 12, 120 -; NO_ISEL-NEXT: li 3, 23 +; NO_ISEL-NEXT: li 4, 120 +; NO_ISEL-NEXT: li 3, 5 ; NO_ISEL-NEXT: bc 12, 1, .LBB32_1 -; NO_ISEL-NEXT: b .LBB32_2 +; NO_ISEL-NEXT: blr ; NO_ISEL-NEXT: .LBB32_1: ; NO_ISEL-NEXT: addi 3, 4, 0 -; NO_ISEL-NEXT: .LBB32_2: -; NO_ISEL-NEXT: divwu 4, 12, 3 -; NO_ISEL-NEXT: mullw 3, 4, 3 -; NO_ISEL-NEXT: subfic 3, 3, 120 ; NO_ISEL-NEXT: blr %sel = select i1 %cond, i8 -4, i8 23 %bo = urem i8 120, %sel @@ -897,25 +862,31 @@ } define double @fsub_constant_sel_constants(i1 %cond) { -; ALL-LABEL: fsub_constant_sel_constants: -; ALL: # %bb.0: -; ALL-NEXT: andi. 3, 3, 1 -; ALL-NEXT: bc 12, 1, .LBB44_2 -; ALL-NEXT: # %bb.1: -; ALL-NEXT: addis 3, 2, .LCPI44_0@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI44_0@toc@l -; ALL-NEXT: lfdx 0, 0, 3 -; ALL-NEXT: b .LBB44_3 -; ALL-NEXT: .LBB44_2: -; ALL-NEXT: addis 3, 2, .LCPI44_1@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI44_1@toc@l -; ALL-NEXT: lfsx 0, 0, 3 -; ALL-NEXT: .LBB44_3: -; ALL-NEXT: addis 3, 2, .LCPI44_2@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI44_2@toc@l -; ALL-NEXT: lfdx 1, 0, 3 -; ALL-NEXT: xssubdp 1, 1, 0 -; ALL-NEXT: blr +; ISEL-LABEL: fsub_constant_sel_constants: +; ISEL: # %bb.0: +; ISEL-NEXT: andi. 3, 3, 1 +; ISEL-NEXT: addis 4, 2, .LCPI44_0@toc@ha +; ISEL-NEXT: addis 3, 2, .LCPI44_1@toc@ha +; ISEL-NEXT: addi 4, 4, .LCPI44_0@toc@l +; ISEL-NEXT: addi 3, 3, .LCPI44_1@toc@l +; ISEL-NEXT: isel 3, 3, 4, 1 +; ISEL-NEXT: lfdx 1, 0, 3 +; ISEL-NEXT: blr +; +; NO_ISEL-LABEL: fsub_constant_sel_constants: +; NO_ISEL: # %bb.0: +; NO_ISEL-NEXT: andi. 3, 3, 1 +; NO_ISEL-NEXT: addis 4, 2, .LCPI44_0@toc@ha +; NO_ISEL-NEXT: addis 3, 2, .LCPI44_1@toc@ha +; NO_ISEL-NEXT: addi 4, 4, .LCPI44_0@toc@l +; NO_ISEL-NEXT: addi 3, 3, .LCPI44_1@toc@l +; NO_ISEL-NEXT: bc 12, 1, .LBB44_2 +; NO_ISEL-NEXT: # %bb.1: +; NO_ISEL-NEXT: ori 3, 4, 0 +; NO_ISEL-NEXT: b .LBB44_2 +; NO_ISEL-NEXT: .LBB44_2: +; NO_ISEL-NEXT: lfdx 1, 0, 3 +; NO_ISEL-NEXT: blr %sel = select i1 %cond, double -4.0, double 23.3 %bo = fsub double 5.1, %sel ret double %bo @@ -984,25 +955,31 @@ } define double @fdiv_constant_sel_constants(i1 %cond) { -; ALL-LABEL: fdiv_constant_sel_constants: -; ALL: # %bb.0: -; ALL-NEXT: andi. 3, 3, 1 -; ALL-NEXT: bc 12, 1, .LBB47_2 -; ALL-NEXT: # %bb.1: -; ALL-NEXT: addis 3, 2, .LCPI47_0@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI47_0@toc@l -; ALL-NEXT: lfdx 0, 0, 3 -; ALL-NEXT: b .LBB47_3 -; ALL-NEXT: .LBB47_2: -; ALL-NEXT: addis 3, 2, .LCPI47_1@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI47_1@toc@l -; ALL-NEXT: lfsx 0, 0, 3 -; ALL-NEXT: .LBB47_3: -; ALL-NEXT: addis 3, 2, .LCPI47_2@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI47_2@toc@l -; ALL-NEXT: lfdx 1, 0, 3 -; ALL-NEXT: xsdivdp 1, 1, 0 -; ALL-NEXT: blr +; ISEL-LABEL: fdiv_constant_sel_constants: +; ISEL: # %bb.0: +; ISEL-NEXT: andi. 3, 3, 1 +; ISEL-NEXT: addis 4, 2, .LCPI47_0@toc@ha +; ISEL-NEXT: addis 3, 2, .LCPI47_1@toc@ha +; ISEL-NEXT: addi 4, 4, .LCPI47_0@toc@l +; ISEL-NEXT: addi 3, 3, .LCPI47_1@toc@l +; ISEL-NEXT: isel 3, 3, 4, 1 +; ISEL-NEXT: lfdx 1, 0, 3 +; ISEL-NEXT: blr +; +; NO_ISEL-LABEL: fdiv_constant_sel_constants: +; NO_ISEL: # %bb.0: +; NO_ISEL-NEXT: andi. 3, 3, 1 +; NO_ISEL-NEXT: addis 4, 2, .LCPI47_0@toc@ha +; NO_ISEL-NEXT: addis 3, 2, .LCPI47_1@toc@ha +; NO_ISEL-NEXT: addi 4, 4, .LCPI47_0@toc@l +; NO_ISEL-NEXT: addi 3, 3, .LCPI47_1@toc@l +; NO_ISEL-NEXT: bc 12, 1, .LBB47_2 +; NO_ISEL-NEXT: # %bb.1: +; NO_ISEL-NEXT: ori 3, 4, 0 +; NO_ISEL-NEXT: b .LBB47_2 +; NO_ISEL-NEXT: .LBB47_2: +; NO_ISEL-NEXT: lfdx 1, 0, 3 +; NO_ISEL-NEXT: blr %sel = select i1 %cond, double -4.0, double 23.3 %bo = fdiv double 5.1, %sel ret double %bo @@ -1029,34 +1006,31 @@ } define double @frem_constant_sel_constants(i1 %cond) { -; ALL-LABEL: frem_constant_sel_constants: -; ALL: # %bb.0: -; ALL-NEXT: mflr 0 -; ALL-NEXT: std 0, 16(1) -; ALL-NEXT: stdu 1, -32(1) -; ALL-NEXT: .cfi_def_cfa_offset 32 -; ALL-NEXT: .cfi_offset lr, 16 -; ALL-NEXT: andi. 3, 3, 1 -; ALL-NEXT: bc 12, 1, .LBB49_2 -; ALL-NEXT: # %bb.1: -; ALL-NEXT: addis 3, 2, .LCPI49_0@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI49_0@toc@l -; ALL-NEXT: lfdx 2, 0, 3 -; ALL-NEXT: b .LBB49_3 -; ALL-NEXT: .LBB49_2: -; ALL-NEXT: addis 3, 2, .LCPI49_1@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI49_1@toc@l -; ALL-NEXT: lfsx 2, 0, 3 -; ALL-NEXT: .LBB49_3: -; ALL-NEXT: addis 3, 2, .LCPI49_2@toc@ha -; ALL-NEXT: addi 3, 3, .LCPI49_2@toc@l -; ALL-NEXT: lfdx 1, 0, 3 -; ALL-NEXT: bl fmod -; ALL-NEXT: nop -; ALL-NEXT: addi 1, 1, 32 -; ALL-NEXT: ld 0, 16(1) -; ALL-NEXT: mtlr 0 -; ALL-NEXT: blr +; ISEL-LABEL: frem_constant_sel_constants: +; ISEL: # %bb.0: +; ISEL-NEXT: andi. 3, 3, 1 +; ISEL-NEXT: addis 4, 2, .LCPI49_0@toc@ha +; ISEL-NEXT: addis 3, 2, .LCPI49_1@toc@ha +; ISEL-NEXT: addi 4, 4, .LCPI49_0@toc@l +; ISEL-NEXT: addi 3, 3, .LCPI49_1@toc@l +; ISEL-NEXT: isel 3, 3, 4, 1 +; ISEL-NEXT: lfdx 1, 0, 3 +; ISEL-NEXT: blr +; +; NO_ISEL-LABEL: frem_constant_sel_constants: +; NO_ISEL: # %bb.0: +; NO_ISEL-NEXT: andi. 3, 3, 1 +; NO_ISEL-NEXT: addis 4, 2, .LCPI49_0@toc@ha +; NO_ISEL-NEXT: addis 3, 2, .LCPI49_1@toc@ha +; NO_ISEL-NEXT: addi 4, 4, .LCPI49_0@toc@l +; NO_ISEL-NEXT: addi 3, 3, .LCPI49_1@toc@l +; NO_ISEL-NEXT: bc 12, 1, .LBB49_2 +; NO_ISEL-NEXT: # %bb.1: +; NO_ISEL-NEXT: ori 3, 4, 0 +; NO_ISEL-NEXT: b .LBB49_2 +; NO_ISEL-NEXT: .LBB49_2: +; NO_ISEL-NEXT: lfdx 1, 0, 3 +; NO_ISEL-NEXT: blr %sel = select i1 %cond, double -4.0, double 23.3 %bo = frem double 5.1, %sel ret double %bo Index: test/CodeGen/X86/dagcombine-select.ll =================================================================== --- test/CodeGen/X86/dagcombine-select.ll +++ test/CodeGen/X86/dagcombine-select.ll @@ -65,11 +65,9 @@ ; CHECK-LABEL: sel_constants_sub_constant_sel_constants: ; CHECK: # %bb.0: ; CHECK-NEXT: testb $1, %dil -; CHECK-NEXT: movl $-4, %eax -; CHECK-NEXT: movl $3, %ecx -; CHECK-NEXT: cmovnel %eax, %ecx -; CHECK-NEXT: movl $5, %eax -; CHECK-NEXT: subl %ecx, %eax +; CHECK-NEXT: movl $9, %ecx +; CHECK-NEXT: movl $2, %eax +; CHECK-NEXT: cmovnel %ecx, %eax ; CHECK-NEXT: retq %sel = select i1 %cond, i32 -4, i32 3 %bo = sub i32 5, %sel @@ -79,13 +77,10 @@ define i32 @sdiv_constant_sel_constants(i1 %cond) { ; CHECK-LABEL: sdiv_constant_sel_constants: ; CHECK: # %bb.0: -; CHECK-NEXT: testb $1, %dil -; CHECK-NEXT: movl $121, %eax -; CHECK-NEXT: movl $23, %ecx -; CHECK-NEXT: cmovnel %eax, %ecx -; CHECK-NEXT: movl $120, %eax -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: divl %ecx +; CHECK-NEXT: notb %dil +; CHECK-NEXT: movzbl %dil, %eax +; CHECK-NEXT: andl $1, %eax +; CHECK-NEXT: leal (%rax,%rax,4), %eax ; CHECK-NEXT: retq %sel = select i1 %cond, i32 121, i32 23 %bo = sdiv i32 120, %sel @@ -95,13 +90,10 @@ define i32 @udiv_constant_sel_constants(i1 %cond) { ; CHECK-LABEL: udiv_constant_sel_constants: ; CHECK: # %bb.0: -; CHECK-NEXT: testb $1, %dil -; CHECK-NEXT: movl $-4, %eax -; CHECK-NEXT: movl $23, %ecx -; CHECK-NEXT: cmovnel %eax, %ecx -; CHECK-NEXT: movl $120, %eax -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: divl %ecx +; CHECK-NEXT: notb %dil +; CHECK-NEXT: movzbl %dil, %eax +; CHECK-NEXT: andl $1, %eax +; CHECK-NEXT: leal (%rax,%rax,4), %eax ; CHECK-NEXT: retq %sel = select i1 %cond, i32 -4, i32 23 %bo = udiv i32 120, %sel @@ -112,13 +104,9 @@ ; CHECK-LABEL: srem_constant_sel_constants: ; CHECK: # %bb.0: ; CHECK-NEXT: testb $1, %dil -; CHECK-NEXT: movl $121, %eax -; CHECK-NEXT: movl $23, %ecx -; CHECK-NEXT: cmovnel %eax, %ecx -; CHECK-NEXT: movl $120, %eax -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: divl %ecx -; CHECK-NEXT: movl %edx, %eax +; CHECK-NEXT: movl $120, %ecx +; CHECK-NEXT: movl $5, %eax +; CHECK-NEXT: cmovnel %ecx, %eax ; CHECK-NEXT: retq %sel = select i1 %cond, i32 121, i32 23 %bo = srem i32 120, %sel @@ -129,13 +117,9 @@ ; CHECK-LABEL: urem_constant_sel_constants: ; CHECK: # %bb.0: ; CHECK-NEXT: testb $1, %dil -; CHECK-NEXT: movl $-4, %eax -; CHECK-NEXT: movl $23, %ecx -; CHECK-NEXT: cmovnel %eax, %ecx -; CHECK-NEXT: movl $120, %eax -; CHECK-NEXT: xorl %edx, %edx -; CHECK-NEXT: divl %ecx -; CHECK-NEXT: movl %edx, %eax +; CHECK-NEXT: movl $120, %ecx +; CHECK-NEXT: movl $5, %eax +; CHECK-NEXT: cmovnel %ecx, %eax ; CHECK-NEXT: retq %sel = select i1 %cond, i32 -4, i32 23 %bo = urem i32 120, %sel @@ -190,13 +174,10 @@ ; CHECK-NEXT: testb $1, %dil ; CHECK-NEXT: jne .LBB12_1 ; CHECK-NEXT: # %bb.2: -; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero -; CHECK-NEXT: jmp .LBB12_3 +; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero +; CHECK-NEXT: retq ; CHECK-NEXT: .LBB12_1: -; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero -; CHECK-NEXT: .LBB12_3: ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero -; CHECK-NEXT: subsd %xmm1, %xmm0 ; CHECK-NEXT: retq %sel = select i1 %cond, double -4.0, double 23.3 %bo = fsub double 5.1, %sel @@ -209,13 +190,10 @@ ; CHECK-NEXT: testb $1, %dil ; CHECK-NEXT: jne .LBB13_1 ; CHECK-NEXT: # %bb.2: -; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero -; CHECK-NEXT: jmp .LBB13_3 +; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero +; CHECK-NEXT: retq ; CHECK-NEXT: .LBB13_1: -; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero -; CHECK-NEXT: .LBB13_3: ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero -; CHECK-NEXT: divsd %xmm1, %xmm0 ; CHECK-NEXT: retq %sel = select i1 %cond, double -4.0, double 23.3 %bo = fdiv double 5.1, %sel @@ -228,13 +206,11 @@ ; CHECK-NEXT: testb $1, %dil ; CHECK-NEXT: jne .LBB14_1 ; CHECK-NEXT: # %bb.2: -; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero -; CHECK-NEXT: jmp fmod # TAILCALL +; CHECK-NEXT: retq ; CHECK-NEXT: .LBB14_1: -; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero ; CHECK-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero -; CHECK-NEXT: jmp fmod # TAILCALL +; CHECK-NEXT: retq %sel = select i1 %cond, double -4.0, double 23.3 %bo = frem double 5.1, %sel ret double %bo