diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5702,6 +5702,21 @@ return ExtractValueInst::Create(UAddOv, 1); } +static Instruction *foldICmpInvariantGroup(ICmpInst &I) { + std::array Ops = {I.getOperand(0), I.getOperand(1)}; + bool Changed = false; + for (Value *&Op : Ops) { + auto *I = dyn_cast(Op); + if (!I || !I->isLaunderOrStripInvariantGroup()) + continue; + Op = I->getOperand(0); + Changed = true; + } + if (!Changed) + return nullptr; + return ICmpInst::Create(Instruction::ICmp, I.getPredicate(), Ops[0], Ops[1]); +} + Instruction *InstCombinerImpl::visitICmpInst(ICmpInst &I) { bool Changed = false; const SimplifyQuery Q = SQ.getWithInstruction(&I); @@ -5942,6 +5957,9 @@ if (Instruction *Res = foldVectorCmp(I, Builder)) return Res; + if (Instruction *Res = foldICmpInvariantGroup(I)) + return Res; + return Changed ? &I : nullptr; } diff --git a/llvm/test/Transforms/InstCombine/invariant.group.ll b/llvm/test/Transforms/InstCombine/invariant.group.ll --- a/llvm/test/Transforms/InstCombine/invariant.group.ll +++ b/llvm/test/Transforms/InstCombine/invariant.group.ll @@ -107,7 +107,6 @@ define i1 @simplifyForCompare(i8* %a) { ; CHECK-LABEL: @simplifyForCompare( -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[A:%.*]]) ; CHECK-NEXT: ret i1 true ; %a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a) @@ -161,10 +160,7 @@ define i1 @icmp1(i8* %a) { ; CHECK-LABEL: @icmp1( -; CHECK-NEXT: [[A2:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[A:%.*]]) -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[A]]) -; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A2]], [[TMP1]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 true ; %a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a) %a3 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a2) @@ -174,9 +170,7 @@ define i1 @icmp2(i8* %a, i8* %b) { ; CHECK-LABEL: @icmp2( -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* [[A:%.*]]) -; CHECK-NEXT: [[TMP2:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[B:%.*]]) -; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[R:%.*]] = icmp eq i8* [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: ret i1 [[R]] ; %a2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %a)