diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 563b45de49836..32f2a30afad48 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1649,31 +1649,26 @@ Instruction *InstCombinerImpl::foldBinopOfSextBoolToSelect(BinaryOperator &BO) { return SelectInst::Create(X, TVal, FVal); } -static Constant *constantFoldOperationIntoSelectOperand(Instruction &I, - SelectInst *SI, - bool IsTrueArm) { - SmallVector ConstOps; +static Value *simplifyOperationIntoSelectOperand(Instruction &I, SelectInst *SI, + bool IsTrueArm) { + SmallVector Ops; for (Value *Op : I.operands()) { - Constant *C = nullptr; + Value *V = nullptr; if (Op == SI) { - C = dyn_cast(IsTrueArm ? SI->getTrueValue() - : SI->getFalseValue()); + V = IsTrueArm ? SI->getTrueValue() : SI->getFalseValue(); } else if (match(SI->getCondition(), m_SpecificICmp(IsTrueArm ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE, - m_Specific(Op), m_Constant(C))) && - isGuaranteedNotToBeUndefOrPoison(C)) { + m_Specific(Op), m_Value(V))) && + isGuaranteedNotToBeUndefOrPoison(V)) { // Pass } else { - C = dyn_cast(Op); + V = Op; } - if (C == nullptr) - return nullptr; - - ConstOps.push_back(C); + Ops.push_back(V); } - return ConstantFoldInstOperands(&I, ConstOps, I.getDataLayout()); + return simplifyInstructionWithOperands(&I, Ops, I.getDataLayout()); } static Value *foldOperationIntoSelectOperand(Instruction &I, SelectInst *SI, @@ -1681,7 +1676,7 @@ static Value *foldOperationIntoSelectOperand(Instruction &I, SelectInst *SI, Instruction *Clone = I.clone(); Clone->replaceUsesOfWith(SI, NewOp); Clone->dropUBImplyingAttrsAndMetadata(); - IC.InsertNewInstBefore(Clone, SI->getIterator()); + IC.InsertNewInstBefore(Clone, I.getIterator()); return Clone; } @@ -1693,8 +1688,6 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI, Value *TV = SI->getTrueValue(); Value *FV = SI->getFalseValue(); - if (!(isa(TV) || isa(FV))) - return nullptr; // Bool selects with constant operands can be folded to logical ops. if (SI->getType()->isIntOrIntVectorTy(1)) @@ -1715,9 +1708,10 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI, } } - // Make sure that one of the select arms constant folds successfully. - Value *NewTV = constantFoldOperationIntoSelectOperand(Op, SI, /*IsTrueArm*/ true); - Value *NewFV = constantFoldOperationIntoSelectOperand(Op, SI, /*IsTrueArm*/ false); + // Make sure that one of the select arms folds successfully. + Value *NewTV = simplifyOperationIntoSelectOperand(Op, SI, /*IsTrueArm=*/true); + Value *NewFV = + simplifyOperationIntoSelectOperand(Op, SI, /*IsTrueArm=*/false); if (!NewTV && !NewFV) return nullptr; diff --git a/llvm/test/Transforms/InstCombine/cast-mul-select.ll b/llvm/test/Transforms/InstCombine/cast-mul-select.ll index 6eb3a8c0a2049..7999aa5e8ae07 100644 --- a/llvm/test/Transforms/InstCombine/cast-mul-select.ll +++ b/llvm/test/Transforms/InstCombine/cast-mul-select.ll @@ -73,10 +73,10 @@ define i8 @select2(i1 %cond, i8 %x, i8 %y, i8 %z) { ; DBGINFO-NEXT: #dbg_value(i8 [[Z:%.*]], [[META39:![0-9]+]], !DIExpression(DW_OP_LLVM_convert, 8, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_stack_value), [[META45:![0-9]+]]) ; DBGINFO-NEXT: [[D:%.*]] = add i8 [[X]], [[Y]], !dbg [[DBG46:![0-9]+]] ; DBGINFO-NEXT: #dbg_value(!DIArgList(i8 [[X]], i8 [[Y]]), [[META40:![0-9]+]], !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_convert, 8, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_LLVM_arg, 1, DW_OP_LLVM_convert, 8, DW_ATE_unsigned, DW_OP_LLVM_convert, 32, DW_ATE_unsigned, DW_OP_plus, DW_OP_stack_value), [[DBG46]]) -; DBGINFO-NEXT: [[E:%.*]] = select i1 [[COND:%.*]], i8 [[Z]], i8 [[D]], !dbg [[DBG47:![0-9]+]] -; DBGINFO-NEXT: #dbg_value(i32 poison, [[META41:![0-9]+]], !DIExpression(), [[DBG47]]) -; DBGINFO-NEXT: #dbg_value(i8 [[E]], [[META42:![0-9]+]], !DIExpression(), [[META48:![0-9]+]]) -; DBGINFO-NEXT: ret i8 [[E]], !dbg [[DBG49:![0-9]+]] +; DBGINFO-NEXT: #dbg_value(i32 poison, [[META41:![0-9]+]], !DIExpression(), [[META47:![0-9]+]]) +; DBGINFO-NEXT: [[F:%.*]] = select i1 [[COND:%.*]], i8 [[Z]], i8 [[D]], !dbg [[META47]] +; DBGINFO-NEXT: #dbg_value(i8 [[F]], [[META42:![0-9]+]], !DIExpression(), [[META48:![0-9]+]]) +; DBGINFO-NEXT: ret i8 [[F]], !dbg [[DBG49:![0-9]+]] ; %A = zext i8 %x to i32 %B = zext i8 %y to i32 diff --git a/llvm/test/Transforms/InstCombine/extract-select-agg.ll b/llvm/test/Transforms/InstCombine/extract-select-agg.ll index 65d00565cc431..3a3da6f6380e6 100644 --- a/llvm/test/Transforms/InstCombine/extract-select-agg.ll +++ b/llvm/test/Transforms/InstCombine/extract-select-agg.ll @@ -56,14 +56,9 @@ define void @test_select_agg_multiuse(i1 %cond, i64 %v1, i64 %v2, i64 %v3, i64 % ; CHECK-LABEL: define void @test_select_agg_multiuse( ; CHECK-SAME: i1 [[COND:%.*]], i64 [[V1:%.*]], i64 [[V2:%.*]], i64 [[V3:%.*]], i64 [[V4:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[A0:%.*]] = insertvalue { i64, i64 } poison, i64 [[V1]], 0 -; CHECK-NEXT: [[A1:%.*]] = insertvalue { i64, i64 } [[A0]], i64 [[V2]], 1 -; CHECK-NEXT: [[B0:%.*]] = insertvalue { i64, i64 } poison, i64 [[V3]], 0 -; CHECK-NEXT: [[B1:%.*]] = insertvalue { i64, i64 } [[B0]], i64 [[V4]], 1 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND]], { i64, i64 } [[A1]], { i64, i64 } [[B1]] -; CHECK-NEXT: [[X:%.*]] = extractvalue { i64, i64 } [[SEL]], 0 +; CHECK-NEXT: [[X:%.*]] = select i1 [[COND]], i64 [[V1]], i64 [[V3]] ; CHECK-NEXT: call void @use(i64 [[X]]) -; CHECK-NEXT: [[Y:%.*]] = extractvalue { i64, i64 } [[SEL]], 1 +; CHECK-NEXT: [[Y:%.*]] = select i1 [[COND]], i64 [[V2]], i64 [[V4]] ; CHECK-NEXT: call void @use(i64 [[Y]]) ; CHECK-NEXT: ret void ; @@ -88,10 +83,8 @@ define i64 @test_extract_select_insert_left(ptr %p1, i64 %v) { ; CHECK-NEXT: [[CALL:%.*]] = call { ptr, i64 } @foo() ; CHECK-NEXT: [[ELM1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[ELM1]], [[V]] -; CHECK-NEXT: [[FCA0:%.*]] = insertvalue { ptr, i64 } poison, ptr [[P1]], 0 -; CHECK-NEXT: [[FCA1:%.*]] = insertvalue { ptr, i64 } [[FCA0]], i64 4294967294, 1 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], { ptr, i64 } [[FCA1]], { ptr, i64 } [[CALL]] -; CHECK-NEXT: [[RES:%.*]] = extractvalue { ptr, i64 } [[SELECT]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1 +; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i64 4294967294, i64 [[TMP1]] ; CHECK-NEXT: ret i64 [[RES]] ; %call = call { ptr, i64 } @foo() @@ -110,10 +103,8 @@ define i64 @test_extract_select_insert_right(ptr %p1, i64 %v) { ; CHECK-NEXT: [[CALL:%.*]] = call { ptr, i64 } @foo() ; CHECK-NEXT: [[ELM1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1 ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[ELM1]], [[V]] -; CHECK-NEXT: [[FCA0:%.*]] = insertvalue { ptr, i64 } poison, ptr [[P1]], 0 -; CHECK-NEXT: [[FCA1:%.*]] = insertvalue { ptr, i64 } [[FCA0]], i64 4294967294, 1 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], { ptr, i64 } [[CALL]], { ptr, i64 } [[FCA1]] -; CHECK-NEXT: [[RES:%.*]] = extractvalue { ptr, i64 } [[SELECT]], 1 +; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i64 } [[CALL]], 1 +; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i64 [[TMP1]], i64 4294967294 ; CHECK-NEXT: ret i64 [[RES]] ; %call = call { ptr, i64 } @foo() diff --git a/llvm/test/Transforms/InstCombine/fptrunc.ll b/llvm/test/Transforms/InstCombine/fptrunc.ll index 825868b107033..f46940ff060d4 100644 --- a/llvm/test/Transforms/InstCombine/fptrunc.ll +++ b/llvm/test/Transforms/InstCombine/fptrunc.ll @@ -52,7 +52,7 @@ define <2 x half> @fmul_constant_op1(<2 x float> %x) { define float @fptrunc_select_true_val(float %x, double %y, i1 %cond) { ; CHECK-LABEL: @fptrunc_select_true_val( ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc double [[Y:%.*]] to float -; CHECK-NEXT: [[NARROW_SEL:%.*]] = select fast i1 [[COND:%.*]], float [[TMP1]], float [[X:%.*]] +; CHECK-NEXT: [[NARROW_SEL:%.*]] = select i1 [[COND:%.*]], float [[TMP1]], float [[X:%.*]] ; CHECK-NEXT: ret float [[NARROW_SEL]] ; %e = fpext float %x to double @@ -64,7 +64,7 @@ define float @fptrunc_select_true_val(float %x, double %y, i1 %cond) { define <2 x float> @fptrunc_select_false_val(<2 x float> %x, <2 x double> %y, <2 x i1> %cond) { ; CHECK-LABEL: @fptrunc_select_false_val( ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc <2 x double> [[Y:%.*]] to <2 x float> -; CHECK-NEXT: [[NARROW_SEL:%.*]] = select nnan <2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x float> [[TMP1]] +; CHECK-NEXT: [[NARROW_SEL:%.*]] = select <2 x i1> [[COND:%.*]], <2 x float> [[X:%.*]], <2 x float> [[TMP1]] ; CHECK-NEXT: ret <2 x float> [[NARROW_SEL]] ; %e = fpext <2 x float> %x to <2 x double> @@ -80,7 +80,7 @@ define half @fptrunc_select_true_val_extra_use(half %x, float %y, i1 %cond) { ; CHECK-NEXT: [[E:%.*]] = fpext half [[X:%.*]] to float ; CHECK-NEXT: call void @use(float [[E]]) ; CHECK-NEXT: [[TMP1:%.*]] = fptrunc float [[Y:%.*]] to half -; CHECK-NEXT: [[NARROW_SEL:%.*]] = select ninf i1 [[COND:%.*]], half [[TMP1]], half [[X]] +; CHECK-NEXT: [[NARROW_SEL:%.*]] = select i1 [[COND:%.*]], half [[TMP1]], half [[X]] ; CHECK-NEXT: ret half [[NARROW_SEL]] ; %e = fpext half %x to float diff --git a/llvm/test/Transforms/InstCombine/known-never-nan.ll b/llvm/test/Transforms/InstCombine/known-never-nan.ll index 1ca24671d65c4..c4ce874029647 100644 --- a/llvm/test/Transforms/InstCombine/known-never-nan.ll +++ b/llvm/test/Transforms/InstCombine/known-never-nan.ll @@ -20,10 +20,10 @@ define i1 @fabs_sqrt_src_maybe_nan(double %arg0, double %arg1) { define i1 @select_maybe_nan_lhs(i1 %cond, double %lhs, double %arg1) { ; CHECK-LABEL: @select_maybe_nan_lhs( -; CHECK-NEXT: [[RHS:%.*]] = fadd nnan double [[ARG1:%.*]], 1.000000e+00 -; CHECK-NEXT: [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS:%.*]], double [[RHS]] -; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[TMP]] +; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP:%.*]], 0.000000e+00 +; CHECK-NEXT: [[NOT_COND:%.*]] = xor i1 [[COND:%.*]], true +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[NOT_COND]], i1 true, i1 [[TMP]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %rhs = fadd nnan double %arg1, 1.0 %op = select i1 %cond, double %lhs, double %rhs @@ -33,10 +33,9 @@ define i1 @select_maybe_nan_lhs(i1 %cond, double %lhs, double %arg1) { define i1 @select_maybe_nan_rhs(i1 %cond, double %arg0, double %rhs) { ; CHECK-LABEL: @select_maybe_nan_rhs( -; CHECK-NEXT: [[LHS:%.*]] = fadd nnan double [[ARG0:%.*]], 1.000000e+00 -; CHECK-NEXT: [[OP:%.*]] = select i1 [[COND:%.*]], double [[LHS]], double [[RHS:%.*]] -; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP]], 0.000000e+00 -; CHECK-NEXT: ret i1 [[TMP]] +; CHECK-NEXT: [[TMP:%.*]] = fcmp ord double [[OP:%.*]], 0.000000e+00 +; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[COND:%.*]], i1 true, i1 [[TMP]] +; CHECK-NEXT: ret i1 [[TMP1]] ; %lhs = fadd nnan double %arg0, 1.0 %op = select i1 %cond, double %lhs, double %rhs diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index 2baf315c508ee..9e92d227ca447 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -4732,10 +4732,9 @@ define i32 @pr99436(ptr align 4 dereferenceable(4) %ptr) { define i8 @sel_trunc_simplify(i1 %c, i8 %x, i16 %y) { ; CHECK-LABEL: @sel_trunc_simplify( -; CHECK-NEXT: [[X_EXT:%.*]] = zext i8 [[X:%.*]] to i16 -; CHECK-NEXT: [[Y:%.*]] = select i1 [[C:%.*]], i16 [[X_EXT]], i16 [[Y1:%.*]] -; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 [[Y]] to i8 -; CHECK-NEXT: ret i8 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = trunc i16 [[Y:%.*]] to i8 +; CHECK-NEXT: [[TRUNC:%.*]] = select i1 [[C:%.*]], i8 [[X:%.*]], i8 [[TMP1]] +; CHECK-NEXT: ret i8 [[TRUNC]] ; %x.ext = zext i8 %x to i16 %sel = select i1 %c, i16 %x.ext, i16 %y @@ -4745,10 +4744,10 @@ define i8 @sel_trunc_simplify(i1 %c, i8 %x, i16 %y) { define i32 @sel_umin_simplify(i1 %c, i32 %x, i16 %y) { ; CHECK-LABEL: @sel_umin_simplify( -; CHECK-NEXT: [[X:%.*]] = select i1 [[C:%.*]], i32 [[X1:%.*]], i32 0 ; CHECK-NEXT: [[ARG2_EXT:%.*]] = zext i16 [[ARG2:%.*]] to i32 -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X]], i32 [[ARG2_EXT]]) -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.umin.i32(i32 [[X:%.*]], i32 [[ARG2_EXT]]) +; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 0 +; CHECK-NEXT: ret i32 [[RES]] ; %sel = select i1 %c, i32 %x, i32 0 %y.ext = zext i16 %y to i32 @@ -4758,11 +4757,9 @@ define i32 @sel_umin_simplify(i1 %c, i32 %x, i16 %y) { define i32 @sel_extractvalue_simplify(i1 %c, { i32, i32 } %agg1, i32 %x, i32 %y) { ; CHECK-LABEL: @sel_extractvalue_simplify( -; CHECK-NEXT: [[AGG2_0:%.*]] = insertvalue { i32, i32 } poison, i32 [[X:%.*]], 0 -; CHECK-NEXT: [[AGG2_1:%.*]] = insertvalue { i32, i32 } [[AGG2_0]], i32 [[Y:%.*]], 1 -; CHECK-NEXT: [[AGG1:%.*]] = select i1 [[C:%.*]], { i32, i32 } [[AGG2:%.*]], { i32, i32 } [[AGG2_1]] -; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i32 } [[AGG1]], 1 -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i32 } [[AGG1:%.*]], 1 +; CHECK-NEXT: [[RES:%.*]] = select i1 [[C:%.*]], i32 [[TMP1]], i32 [[Y:%.*]] +; CHECK-NEXT: ret i32 [[RES]] ; %agg2.0 = insertvalue { i32, i32 } poison, i32 %x, 0 %agg2.1 = insertvalue { i32, i32 } %agg2.0, i32 %y, 1 diff --git a/llvm/test/Transforms/LoopVectorize/AArch64/deterministic-type-shrinkage.ll b/llvm/test/Transforms/LoopVectorize/AArch64/deterministic-type-shrinkage.ll index 2ba460255c607..7642d0d36be7b 100644 --- a/llvm/test/Transforms/LoopVectorize/AArch64/deterministic-type-shrinkage.ll +++ b/llvm/test/Transforms/LoopVectorize/AArch64/deterministic-type-shrinkage.ll @@ -393,7 +393,6 @@ define void @replicate_operands_in_with_operands_in_minbws(ptr %dst, ptr noalias ; CHECK-LABEL: define void @replicate_operands_in_with_operands_in_minbws ; CHECK-SAME: (ptr [[DST:%.*]], ptr noalias [[SRC_1:%.*]], ptr noalias [[SRC_2:%.*]], i32 [[X:%.*]]) { ; CHECK-NEXT: entry: -; CHECK-NEXT: [[SUB:%.*]] = add i32 [[X]], 65526 ; CHECK-NEXT: br label [[LOOP_HEADER:%.*]] ; CHECK: loop.header: ; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP_LATCH:%.*]] ] @@ -405,10 +404,10 @@ define void @replicate_operands_in_with_operands_in_minbws(ptr %dst, ptr noalias ; CHECK-NEXT: [[GEP_SRC_2:%.*]] = getelementptr inbounds i16, ptr [[SRC_2]], i64 [[IV]] ; CHECK-NEXT: [[L_2:%.*]] = load i16, ptr [[GEP_SRC_2]], align 2 ; CHECK-NEXT: [[C_2:%.*]] = icmp ult i16 [[L_2]], 100 -; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[L_2]] to i32 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C_2]], i32 [[SUB]], i32 [[CONV]] -; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[SEL]] to i16 -; CHECK-NEXT: [[TRUNC:%.*]] = add i16 [[L_2]], [[TMP0]] +; CHECK-NEXT: [[TMP0:%.*]] = trunc i32 [[X]] to i16 +; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[TMP0]], -10 +; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[C_2]], i16 [[TMP1]], i16 [[L_2]] +; CHECK-NEXT: [[TRUNC:%.*]] = add i16 [[TMP2]], [[L_2]] ; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr inbounds i32, ptr [[DST]], i64 [[IV]] ; CHECK-NEXT: store i16 [[TRUNC]], ptr [[GEP_DST]], align 2 ; CHECK-NEXT: br label [[LOOP_LATCH]]