[llvm] [InstCombine] simplify `icmp pred x, ~x` (PR #73990)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 13 01:28:50 PST 2023


================
@@ -5,6 +5,521 @@ declare void @llvm.assume(i1)
 declare void @barrier()
 declare void @use.i8(i8)
 
+; X op ~X tests. op signed
+; X s< ~X   -->      X s< 0
+define i1 @src_slt(i8 %x) {
+; CHECK-LABEL: @src_slt(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i8 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %not = xor i8 %x, -1
+  %cmp = icmp slt i8 %x, %not
+  ret i1 %cmp
+}
+define i1 @src_slt_i128(i128 %x) {
+; CHECK-LABEL: @src_slt_i128(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i128 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %not = xor i128 %x, -1
+  %cmp = icmp slt i128 %x, %not
+  ret i1 %cmp
+}
+; X s> ~X   -->     X s> -1
+define i1 @src_sgt(i8 %x) {
+; CHECK-LABEL: @src_sgt(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i8 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %not = xor i8 %x, -1
+  %cmp = icmp sgt i8 %x, %not
+  ret i1 %cmp
+}
+define i1 @src_sgt_i128(i128 %x) {
+; CHECK-LABEL: @src_sgt_i128(
+; CHECK-NEXT:    [[CMP:%.*]] = icmp sgt i128 [[X:%.*]], -1
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+  %not = xor i128 %x, -1
+  %cmp = icmp sgt i128 %x, %not
+  ret i1 %cmp
+}
+; X s<= ~X   -->      X s< 0
+define i1 @src_sle(i8 %x) {
----------------
nikic wrote:

Please take a look at this: https://llvm.godbolt.org/z/zvMcnvsE4 Currently, the src_sle and src_sle_comm (and other comm pairs) actually all test the case where the not is on the left hand side. To test the case where the not is on the right hand side, you need to introduce an additional, higher-complexity operation, like a mul in this example.

The other thing I noticed is that predicates already get canonicalized to from non-strict to strict, apparently thanks to this transform: https://github.com/llvm/llvm-project/blob/1c494198c3f2abc3b10b02e704a0129de74e47d2/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp#L4537 I don't think this really changes anything for your patch, but it indicates that maybe there is some generalization that doesn't require the xor constant to be -1. But let's leave that for another patch...

https://github.com/llvm/llvm-project/pull/73990


More information about the llvm-commits mailing list