diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index a2ff8f3eef819..7c1aff445524d 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -4920,8 +4920,9 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I, } } - if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() && BO0->hasOneUse() && - BO1->hasOneUse() && BO0->getOperand(1) == BO1->getOperand(1)) { + if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() && + (BO0->hasOneUse() || BO1->hasOneUse()) && + BO0->getOperand(1) == BO1->getOperand(1)) { switch (BO0->getOpcode()) { default: break; diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 1f554c7b60256..10ab1fe118348 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -815,6 +815,51 @@ define i1 @test46(i32 %X, i32 %Y, i32 %Z) { ret i1 %C } +define i1 @test46_multiuse1(i32 %X, i32 %Y, i32 %Z) { +; CHECK-LABEL: @test46_multiuse1( +; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]] +; CHECK-NEXT: call void @use_i32(i32 [[A]]) +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[C]] +; + %A = ashr exact i32 %X, %Z + call void @use_i32(i32 %A) + %B = ashr exact i32 %Y, %Z + %C = icmp ult i32 %A, %B + ret i1 %C +} + +define i1 @test46_multiuse2(i32 %X, i32 %Y, i32 %Z) { +; CHECK-LABEL: @test46_multiuse2( +; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z:%.*]] +; CHECK-NEXT: call void @use_i32(i32 [[B]]) +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[X:%.*]], [[Y]] +; CHECK-NEXT: ret i1 [[C]] +; + %A = ashr exact i32 %X, %Z + %B = ashr exact i32 %Y, %Z + call void @use_i32(i32 %B) + %C = icmp ult i32 %A, %B + ret i1 %C +} + +define i1 @test46_multiuse3(i32 %X, i32 %Y, i32 %Z) { +; CHECK-LABEL: @test46_multiuse3( +; CHECK-NEXT: [[A:%.*]] = ashr exact i32 [[X:%.*]], [[Z:%.*]] +; CHECK-NEXT: call void @use_i32(i32 [[A]]) +; CHECK-NEXT: [[B:%.*]] = ashr exact i32 [[Y:%.*]], [[Z]] +; CHECK-NEXT: call void @use_i32(i32 [[B]]) +; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], [[B]] +; CHECK-NEXT: ret i1 [[C]] +; + %A = ashr exact i32 %X, %Z + call void @use_i32(i32 %A) + %B = ashr exact i32 %Y, %Z + call void @use_i32(i32 %B) + %C = icmp ult i32 %A, %B + ret i1 %C +} + ; PR9343 #5 define i1 @test47(i32 %X, i32 %Y, i32 %Z) { ; CHECK-LABEL: @test47(