Index: llvm/lib/CodeGen/SelectOptimize.cpp =================================================================== --- llvm/lib/CodeGen/SelectOptimize.cpp +++ llvm/lib/CodeGen/SelectOptimize.cpp @@ -515,12 +515,27 @@ } } +static bool isSpecialSelect(SelectInst *SI) { + using namespace llvm::PatternMatch; + + // If the select is a logical-and/logical-or then it is better treated as a + // and/or by the backend. + if (match(SI, m_CombineOr(m_LogicalAnd(m_Value(), m_Value()), + m_LogicalOr(m_Value(), m_Value())))) + return true; + + return false; +} + void SelectOptimize::collectSelectGroups(BasicBlock &BB, SelectGroups &SIGroups) { BasicBlock::iterator BBIt = BB.begin(); while (BBIt != BB.end()) { Instruction *I = &*BBIt++; if (SelectInst *SI = dyn_cast(I)) { + if (isSpecialSelect(SI)) + continue; + SelectGroup SIGroup; SIGroup.push_back(SI); while (BBIt != BB.end()) { Index: llvm/test/CodeGen/AArch64/selectopt-logical.ll =================================================================== --- llvm/test/CodeGen/AArch64/selectopt-logical.ll +++ llvm/test/CodeGen/AArch64/selectopt-logical.ll @@ -14,9 +14,9 @@ ; CHECK-NEXT: [[RES_0_LCSSA:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[OR]], [[INNER_LOOP_010_EXIT]] ] ; CHECK-NEXT: ret i32 [[RES_0_LCSSA]] ; CHECK: for.body.i: -; CHECK-NEXT: [[INDVARS_IV_I:%.*]] = phi i64 [ 0, [[FOR_BODY_I_PREHEADER]] ], [ [[INDVARS_IV_NEXT_I_4:%.*]], [[SELECT_END24:%.*]] ] -; CHECK-NEXT: [[ALL_0_OFF010_I:%.*]] = phi i1 [ true, [[FOR_BODY_I_PREHEADER]] ], [ [[ALL_0_OFF0__I_4:%.*]], [[SELECT_END24]] ] -; CHECK-NEXT: [[ANY_0_OFF09_I:%.*]] = phi i1 [ false, [[FOR_BODY_I_PREHEADER]] ], [ [[DOTANY_0_OFF0_I_4:%.*]], [[SELECT_END24]] ] +; CHECK-NEXT: [[INDVARS_IV_I:%.*]] = phi i64 [ 0, [[FOR_BODY_I_PREHEADER]] ], [ [[INDVARS_IV_NEXT_I_4:%.*]], [[FOR_BODY_I]] ] +; CHECK-NEXT: [[ALL_0_OFF010_I:%.*]] = phi i1 [ true, [[FOR_BODY_I_PREHEADER]] ], [ [[ALL_0_OFF0__I_4:%.*]], [[FOR_BODY_I]] ] +; CHECK-NEXT: [[ANY_0_OFF09_I:%.*]] = phi i1 [ false, [[FOR_BODY_I_PREHEADER]] ], [ [[DOTANY_0_OFF0_I_4:%.*]], [[FOR_BODY_I]] ] ; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, ptr [[X:%.*]], i64 [[INDVARS_IV_I]] ; CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX_I]], align 4 ; CHECK-NEXT: [[CMP1_I:%.*]] = fcmp fast olt float [[TMP0]], 0.000000e+00 @@ -36,66 +36,16 @@ ; CHECK-NEXT: [[ARRAYIDX_I_4:%.*]] = getelementptr inbounds float, ptr [[X]], i64 [[INDVARS_IV_NEXT_I_3]] ; CHECK-NEXT: [[TMP4:%.*]] = load float, ptr [[ARRAYIDX_I_4]], align 4 ; CHECK-NEXT: [[CMP1_I_4:%.*]] = fcmp fast olt float [[TMP4]], 0.000000e+00 -; CHECK-NEXT: [[DOTFROZEN:%.*]] = freeze i1 [[CMP1_I_4]] -; CHECK-NEXT: br i1 [[DOTFROZEN]], label [[SELECT_END:%.*]], label [[SELECT_FALSE:%.*]] -; CHECK: select.false: -; CHECK-NEXT: br label [[SELECT_END]] -; CHECK: select.end: -; CHECK-NEXT: [[TMP5:%.*]] = phi i1 [ true, [[FOR_BODY_I]] ], [ [[CMP1_I_3]], [[SELECT_FALSE]] ] -; CHECK-NEXT: [[DOTFROZEN3:%.*]] = freeze i1 [[TMP5]] -; CHECK-NEXT: br i1 [[DOTFROZEN3]], label [[SELECT_END1:%.*]], label [[SELECT_FALSE2:%.*]] -; CHECK: select.false2: -; CHECK-NEXT: br label [[SELECT_END1]] -; CHECK: select.end1: -; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ true, [[SELECT_END]] ], [ [[CMP1_I_2]], [[SELECT_FALSE2]] ] -; CHECK-NEXT: [[DOTFROZEN6:%.*]] = freeze i1 [[TMP6]] -; CHECK-NEXT: br i1 [[DOTFROZEN6]], label [[SELECT_END4:%.*]], label [[SELECT_FALSE5:%.*]] -; CHECK: select.false5: -; CHECK-NEXT: br label [[SELECT_END4]] -; CHECK: select.end4: -; CHECK-NEXT: [[TMP7:%.*]] = phi i1 [ true, [[SELECT_END1]] ], [ [[CMP1_I_1]], [[SELECT_FALSE5]] ] -; CHECK-NEXT: [[DOTFROZEN9:%.*]] = freeze i1 [[TMP7]] -; CHECK-NEXT: br i1 [[DOTFROZEN9]], label [[SELECT_END7:%.*]], label [[SELECT_FALSE8:%.*]] -; CHECK: select.false8: -; CHECK-NEXT: br label [[SELECT_END7]] -; CHECK: select.end7: -; CHECK-NEXT: [[TMP8:%.*]] = phi i1 [ true, [[SELECT_END4]] ], [ [[CMP1_I]], [[SELECT_FALSE8]] ] -; CHECK-NEXT: [[DOTANY_0_OFF0_I_4_FROZEN:%.*]] = freeze i1 [[TMP8]] -; CHECK-NEXT: br i1 [[DOTANY_0_OFF0_I_4_FROZEN]], label [[SELECT_END10:%.*]], label [[SELECT_FALSE11:%.*]] -; CHECK: select.false11: -; CHECK-NEXT: br label [[SELECT_END10]] -; CHECK: select.end10: -; CHECK-NEXT: [[DOTANY_0_OFF0_I_4]] = phi i1 [ true, [[SELECT_END7]] ], [ [[ANY_0_OFF09_I]], [[SELECT_FALSE11]] ] -; CHECK-NEXT: [[DOTFROZEN14:%.*]] = freeze i1 [[CMP1_I_4]] -; CHECK-NEXT: br i1 [[DOTFROZEN14]], label [[SELECT_END12:%.*]], label [[SELECT_FALSE13:%.*]] -; CHECK: select.false13: -; CHECK-NEXT: br label [[SELECT_END12]] -; CHECK: select.end12: -; CHECK-NEXT: [[TMP9:%.*]] = phi i1 [ [[CMP1_I_3]], [[SELECT_END10]] ], [ false, [[SELECT_FALSE13]] ] -; CHECK-NEXT: [[DOTFROZEN17:%.*]] = freeze i1 [[TMP9]] -; CHECK-NEXT: br i1 [[DOTFROZEN17]], label [[SELECT_END15:%.*]], label [[SELECT_FALSE16:%.*]] -; CHECK: select.false16: -; CHECK-NEXT: br label [[SELECT_END15]] -; CHECK: select.end15: -; CHECK-NEXT: [[TMP10:%.*]] = phi i1 [ [[CMP1_I_2]], [[SELECT_END12]] ], [ false, [[SELECT_FALSE16]] ] -; CHECK-NEXT: [[DOTFROZEN20:%.*]] = freeze i1 [[TMP10]] -; CHECK-NEXT: br i1 [[DOTFROZEN20]], label [[SELECT_END18:%.*]], label [[SELECT_FALSE19:%.*]] -; CHECK: select.false19: -; CHECK-NEXT: br label [[SELECT_END18]] -; CHECK: select.end18: -; CHECK-NEXT: [[TMP11:%.*]] = phi i1 [ [[CMP1_I_1]], [[SELECT_END15]] ], [ false, [[SELECT_FALSE19]] ] -; CHECK-NEXT: [[DOTFROZEN23:%.*]] = freeze i1 [[TMP11]] -; CHECK-NEXT: br i1 [[DOTFROZEN23]], label [[SELECT_END21:%.*]], label [[SELECT_FALSE22:%.*]] -; CHECK: select.false22: -; CHECK-NEXT: br label [[SELECT_END21]] -; CHECK: select.end21: -; CHECK-NEXT: [[TMP12:%.*]] = phi i1 [ [[CMP1_I]], [[SELECT_END18]] ], [ false, [[SELECT_FALSE22]] ] -; CHECK-NEXT: [[ALL_0_OFF0__I_4_FROZEN:%.*]] = freeze i1 [[TMP12]] -; CHECK-NEXT: br i1 [[ALL_0_OFF0__I_4_FROZEN]], label [[SELECT_END24]], label [[SELECT_FALSE25:%.*]] -; CHECK: select.false25: -; CHECK-NEXT: br label [[SELECT_END24]] -; CHECK: select.end24: -; CHECK-NEXT: [[ALL_0_OFF0__I_4]] = phi i1 [ [[ALL_0_OFF010_I]], [[SELECT_END21]] ], [ false, [[SELECT_FALSE25]] ] +; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[CMP1_I_4]], i1 true, i1 [[CMP1_I_3]] +; CHECK-NEXT: [[TMP6:%.*]] = select i1 [[TMP5]], i1 true, i1 [[CMP1_I_2]] +; CHECK-NEXT: [[TMP7:%.*]] = select i1 [[TMP6]], i1 true, i1 [[CMP1_I_1]] +; CHECK-NEXT: [[TMP8:%.*]] = select i1 [[TMP7]], i1 true, i1 [[CMP1_I]] +; CHECK-NEXT: [[DOTANY_0_OFF0_I_4]] = select i1 [[TMP8]], i1 true, i1 [[ANY_0_OFF09_I]] +; CHECK-NEXT: [[TMP9:%.*]] = select i1 [[CMP1_I_4]], i1 [[CMP1_I_3]], i1 false +; CHECK-NEXT: [[TMP10:%.*]] = select i1 [[TMP9]], i1 [[CMP1_I_2]], i1 false +; CHECK-NEXT: [[TMP11:%.*]] = select i1 [[TMP10]], i1 [[CMP1_I_1]], i1 false +; CHECK-NEXT: [[TMP12:%.*]] = select i1 [[TMP11]], i1 [[CMP1_I]], i1 false +; CHECK-NEXT: [[ALL_0_OFF0__I_4]] = select i1 [[TMP12]], i1 [[ALL_0_OFF010_I]], i1 false ; CHECK-NEXT: [[INDVARS_IV_NEXT_I_4]] = add nuw nsw i64 [[INDVARS_IV_I]], 5 ; CHECK-NEXT: [[EXITCOND_NOT_I_4:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT_I_4]], 10000 ; CHECK-NEXT: br i1 [[EXITCOND_NOT_I_4]], label [[INNER_LOOP_010_EXIT]], label [[FOR_BODY_I]]