diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index dff9304be64dd..e576eea4ca36a 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -455,14 +455,20 @@ static Value *foldLogOpOfMaskedICmps_NotAllZeros_BMask_Mixed( // RHS. For example, // (icmp ne (A & 255), 0) & (icmp eq (A & 15), 8) -> (icmp eq (A & 15), 8). // (icmp ne (A & 15), 0) & (icmp eq (A & 15), 8) -> (icmp eq (A & 15), 8). - if (IsSuperSetOrEqual(BCst, DCst)) + if (IsSuperSetOrEqual(BCst, DCst)) { + // We can't guarantee that samesign hold after this fold. + RHS->setSameSign(false); return RHS; + } // Otherwise, B is a subset of D. If B and E have a common bit set, // ie. (B & E) != 0, then LHS is subsumed by RHS. For example. // (icmp ne (A & 12), 0) & (icmp eq (A & 15), 8) -> (icmp eq (A & 15), 8). assert(IsSubSetOrEqual(BCst, DCst) && "Precondition due to above code"); - if ((*BCst & ECst) != 0) + if ((*BCst & ECst) != 0) { + // We can't guarantee that samesign hold after this fold. + RHS->setSameSign(false); return RHS; + } // Otherwise, LHS and RHS contradict and the whole expression becomes false // (or true if negated.) For example, // (icmp ne (A & 7), 0) & (icmp eq (A & 15), 8) -> false. diff --git a/llvm/test/Transforms/InstCombine/icmp-logical.ll b/llvm/test/Transforms/InstCombine/icmp-logical.ll index 50feb51092fd9..df8442e069b78 100644 --- a/llvm/test/Transforms/InstCombine/icmp-logical.ll +++ b/llvm/test/Transforms/InstCombine/icmp-logical.ll @@ -1900,3 +1900,28 @@ define i1 @masked_icmps_bmask_notmixed_not_subset_notoptimized(i32 %A) { %res = and i1 %tst1, %tst2 ret i1 %res } + +define i1 @pr120361(i8 %x, i8 %y) { +; CHECK-LABEL: @pr120361( +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[X:%.*]], -1 +; CHECK-NEXT: ret i1 [[CMP1]] +; + %cmp1 = icmp samesign eq i8 %x, -1 + %cmp2 = icmp ne i8 %x, 0 + %result = select i1 %cmp2, i1 %cmp1, i1 false + ret i1 %result +} + +define i1 @pr120361_v2(i32 %x) { +; CHECK-LABEL: @pr120361_v2( +; CHECK-NEXT: [[AND2:%.*]] = and i32 [[X:%.*]], -113 +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[AND2]], 15 +; CHECK-NEXT: ret i1 [[CMP2]] +; + %and1 = and i32 %x, 15 + %cmp1 = icmp ne i32 %and1, 0 + %and2 = and i32 %x, -113 + %cmp2 = icmp samesign eq i32 %and2, 15 + %and = select i1 %cmp1, i1 %cmp2, i1 false + ret i1 %and +}