diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -2947,6 +2947,17 @@ Constant::getNullValue(NewOr->getType())); } + // (icmp ne A, -1) | (icmp ne B, -1) --> (icmp ne (A&B), -1) + // (icmp eq A, -1) & (icmp eq B, -1) --> (icmp eq (A&B), -1) + // TODO: Remove this when foldLogOpOfMaskedICmps can handle undefs. + if (!IsLogical && PredL == (IsAnd ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE) && + PredL == PredR && match(LHS1, m_ConstantInt<-1>()) && + match(RHS1, m_ConstantInt<-1>()) && LHS0->getType() == RHS0->getType()) { + Value *NewAnd = Builder.CreateAnd(LHS0, RHS0); + return Builder.CreateICmp(PredL, NewAnd, + ConstantInt::get(LHS0->getType(), -1)); + } + // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2). if (!LHSC || !RHSC) return nullptr; diff --git a/llvm/test/Transforms/InstCombine/pr62311.ll b/llvm/test/Transforms/InstCombine/pr62311.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/pr62311.ll @@ -0,0 +1,64 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +; Function Attrs: mustprogress nounwind uwtable +define dso_local noundef zeroext i1 @_Z7allonesDv8_x(<8 x i64> noundef %x) local_unnamed_addr #0 { +; CHECK-LABEL: define dso_local noundef zeroext i1 @_Z7allonesDv8_x +; CHECK-SAME: (<8 x i64> noundef [[X:%.*]]) local_unnamed_addr { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[VECEXT:%.*]] = extractelement <8 x i64> [[X]], i64 0 +; CHECK-NEXT: [[VECEXT1:%.*]] = extractelement <8 x i64> [[X]], i64 1 +; CHECK-NEXT: [[TMP0:%.*]] = and i64 [[VECEXT]], [[VECEXT1]] +; CHECK-NEXT: [[VECEXT4:%.*]] = extractelement <8 x i64> [[X]], i64 2 +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], [[VECEXT4]] +; CHECK-NEXT: [[VECEXT7:%.*]] = extractelement <8 x i64> [[X]], i64 3 +; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], [[VECEXT7]] +; CHECK-NEXT: [[VECEXT10:%.*]] = extractelement <8 x i64> [[X]], i64 4 +; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP2]], [[VECEXT10]] +; CHECK-NEXT: [[VECEXT13:%.*]] = extractelement <8 x i64> [[X]], i64 5 +; CHECK-NEXT: [[TMP4:%.*]] = and i64 [[TMP3]], [[VECEXT13]] +; CHECK-NEXT: [[VECEXT16:%.*]] = extractelement <8 x i64> [[X]], i64 6 +; CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], [[VECEXT16]] +; CHECK-NEXT: [[OR_COND24:%.*]] = icmp eq i64 [[TMP5]], -1 +; CHECK-NEXT: br i1 [[OR_COND24]], label [[LAND_RHS:%.*]], label [[LAND_END:%.*]] +; CHECK: land.rhs: +; CHECK-NEXT: [[VECEXT18:%.*]] = extractelement <8 x i64> [[X]], i64 7 +; CHECK-NEXT: [[CMP19:%.*]] = icmp eq i64 [[VECEXT18]], -1 +; CHECK-NEXT: br label [[LAND_END]] +; CHECK: land.end: +; CHECK-NEXT: [[TMP6:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ [[CMP19]], [[LAND_RHS]] ] +; CHECK-NEXT: ret i1 [[TMP6]] +; +entry: + %vecext = extractelement <8 x i64> %x, i32 0 + %cmp = icmp eq i64 %vecext, -1 + %vecext1 = extractelement <8 x i64> %x, i32 1 + %cmp2 = icmp eq i64 %vecext1, -1 + %or.cond = select i1 %cmp, i1 %cmp2, i1 false + %vecext4 = extractelement <8 x i64> %x, i32 2 + %cmp5 = icmp eq i64 %vecext4, -1 + %or.cond20 = select i1 %or.cond, i1 %cmp5, i1 false + %vecext7 = extractelement <8 x i64> %x, i32 3 + %cmp8 = icmp eq i64 %vecext7, -1 + %or.cond21 = select i1 %or.cond20, i1 %cmp8, i1 false + %vecext10 = extractelement <8 x i64> %x, i32 4 + %cmp11 = icmp eq i64 %vecext10, -1 + %or.cond22 = select i1 %or.cond21, i1 %cmp11, i1 false + %vecext13 = extractelement <8 x i64> %x, i32 5 + %cmp14 = icmp eq i64 %vecext13, -1 + %or.cond23 = select i1 %or.cond22, i1 %cmp14, i1 false + %vecext16 = extractelement <8 x i64> %x, i32 6 + %cmp17 = icmp eq i64 %vecext16, -1 + %or.cond24 = select i1 %or.cond23, i1 %cmp17, i1 false + br i1 %or.cond24, label %land.rhs, label %land.end + +land.rhs: ; preds = %entry + %vecext18 = extractelement <8 x i64> %x, i32 7 + + %cmp19 = icmp eq i64 %vecext18, -1 + br label %land.end + +land.end: ; preds = %land.rhs, %entry + %0 = phi i1 [ false, %entry ], [ %cmp19, %land.rhs ] + ret i1 %0 +}