diff options
-rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 24 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/cast-mul-select.ll | 29 | ||||
-rw-r--r-- | llvm/test/Transforms/InstCombine/icmp-mul-zext.ll | 7 |
3 files changed, 30 insertions, 30 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 9046c36dee8..4eaf2fd72f4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -185,14 +185,8 @@ Value *InstCombiner::EvaluateInDifferentType(Value *V, Type *Ty, case Instruction::Shl: case Instruction::UDiv: case Instruction::URem: { - Value *LHS, *RHS; - if (I->getOperand(0) == I->getOperand(1)) { - // Don't create an unnecessary value if the operands are repeated. - LHS = RHS = EvaluateInDifferentType(I->getOperand(0), Ty, isSigned); - } else { - LHS = EvaluateInDifferentType(I->getOperand(0), Ty, isSigned); - RHS = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned); - } + Value *LHS = EvaluateInDifferentType(I->getOperand(0), Ty, isSigned); + Value *RHS = EvaluateInDifferentType(I->getOperand(1), Ty, isSigned); Res = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); break; } @@ -326,15 +320,11 @@ static bool canNotEvaluateInType(Value *V, Type *Ty) { assert(!isa<Constant>(V) && "Constant should already be handled."); if (!isa<Instruction>(V)) return true; - // We can't extend or shrink something that has multiple uses -- unless those - // multiple uses are all in the same binop instruction -- doing so would - // require duplicating the instruction which isn't profitable. - if (!V->hasOneUse()) { - if (!match(V->user_back(), m_BinOp())) - return true; - if (any_of(V->users(), [&](User *U) { return U != V->user_back(); })) - return true; - } + // We don't extend or shrink something that has multiple uses -- doing so + // would require duplicating the instruction which isn't profitable. + if (!V->hasOneUse()) + return true; + return false; } diff --git a/llvm/test/Transforms/InstCombine/cast-mul-select.ll b/llvm/test/Transforms/InstCombine/cast-mul-select.ll index a72143eac33..3e874874303 100644 --- a/llvm/test/Transforms/InstCombine/cast-mul-select.ll +++ b/llvm/test/Transforms/InstCombine/cast-mul-select.ll @@ -47,11 +47,16 @@ define i8 @select2(i1 %cond, i8 %x, i8 %y, i8 %z) { ret i8 %F } +; The next 3 tests could be handled in instcombine, but evaluating values +; with multiple uses may be very slow. Let some other pass deal with it. + define i32 @eval_trunc_multi_use_in_one_inst(i32 %x) { ; CHECK-LABEL: @eval_trunc_multi_use_in_one_inst( -; CHECK-NEXT: [[A:%.*]] = add i32 [[X:%.*]], 15 -; CHECK-NEXT: [[M:%.*]] = mul i32 [[A]], [[A]] -; CHECK-NEXT: ret i32 [[M]] +; CHECK-NEXT: [[Z:%.*]] = zext i32 [[X:%.*]] to i64 +; CHECK-NEXT: [[A:%.*]] = add nuw nsw i64 [[Z]], 15 +; CHECK-NEXT: [[M:%.*]] = mul i64 [[A]], [[A]] +; CHECK-NEXT: [[T:%.*]] = trunc i64 [[M]] to i32 +; CHECK-NEXT: ret i32 [[T]] ; %z = zext i32 %x to i64 %a = add nsw nuw i64 %z, 15 @@ -62,9 +67,11 @@ define i32 @eval_trunc_multi_use_in_one_inst(i32 %x) { define i32 @eval_zext_multi_use_in_one_inst(i32 %x) { ; CHECK-LABEL: @eval_zext_multi_use_in_one_inst( -; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], 5 -; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[A]], [[A]] -; CHECK-NEXT: ret i32 [[M]] +; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i16 +; CHECK-NEXT: [[A:%.*]] = and i16 [[T]], 5 +; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i16 [[A]], [[A]] +; CHECK-NEXT: [[R:%.*]] = zext i16 [[M]] to i32 +; CHECK-NEXT: ret i32 [[R]] ; %t = trunc i32 %x to i16 %a = and i16 %t, 5 @@ -75,10 +82,12 @@ define i32 @eval_zext_multi_use_in_one_inst(i32 %x) { define i32 @eval_sext_multi_use_in_one_inst(i32 %x) { ; CHECK-LABEL: @eval_sext_multi_use_in_one_inst( -; CHECK-NEXT: [[A:%.*]] = and i32 [[X:%.*]], 14 -; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i32 [[A]], [[A]] -; CHECK-NEXT: [[O:%.*]] = or i32 [[M]], -32768 -; CHECK-NEXT: ret i32 [[O]] +; CHECK-NEXT: [[T:%.*]] = trunc i32 [[X:%.*]] to i16 +; CHECK-NEXT: [[A:%.*]] = and i16 [[T]], 14 +; CHECK-NEXT: [[M:%.*]] = mul nuw nsw i16 [[A]], [[A]] +; CHECK-NEXT: [[O:%.*]] = or i16 [[M]], -32768 +; CHECK-NEXT: [[R:%.*]] = sext i16 [[O]] to i32 +; CHECK-NEXT: ret i32 [[R]] ; %t = trunc i32 %x to i16 %a = and i16 %t, 14 diff --git a/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll b/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll index 848bf0d3c43..8014171fcde 100644 --- a/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll +++ b/llvm/test/Transforms/InstCombine/icmp-mul-zext.ll @@ -55,12 +55,13 @@ lor.end: define void @PR33765(i8 %beth) { ; CHECK-LABEL: @PR33765( -; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[BETH:%.*]] to i16 +; CHECK-NEXT: [[CONV:%.*]] = zext i8 [[BETH:%.*]] to i32 ; CHECK-NEXT: br i1 false, label [[IF_THEN9:%.*]], label [[IF_THEN9]] ; CHECK: if.then9: -; CHECK-NEXT: [[MUL:%.*]] = mul nuw i16 [[CONV]], [[CONV]] +; CHECK-NEXT: [[MUL:%.*]] = mul nuw nsw i32 [[CONV]], [[CONV]] ; CHECK-NEXT: [[TINKY:%.*]] = load i16, i16* @glob, align 2 -; CHECK-NEXT: [[CONV14:%.*]] = and i16 [[TINKY]], [[MUL]] +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[MUL]] to i16 +; CHECK-NEXT: [[CONV14:%.*]] = and i16 [[TINKY]], [[TMP1]] ; CHECK-NEXT: store i16 [[CONV14]], i16* @glob, align 2 ; CHECK-NEXT: ret void ; |