[llvm] 1fb0710 - [NFC][InstCombine] Add tests for conditional negation via math

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 2 10:27:08 PST 2023


Author: Roman Lebedev
Date: 2023-01-02T21:26:37+03:00
New Revision: 1fb07108d4f8606464fad98a49e2cbae7ec4ae25

URL: https://github.com/llvm/llvm-project/commit/1fb07108d4f8606464fad98a49e2cbae7ec4ae25
DIFF: https://github.com/llvm/llvm-project/commit/1fb07108d4f8606464fad98a49e2cbae7ec4ae25.diff

LOG: [NFC][InstCombine] Add tests for conditional negation via math

https://github.com/llvm/llvm-project/issues/59791

Added: 
    llvm/test/Transforms/InstCombine/conditional-negation.ll

Modified: 
    

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/conditional-negation.ll b/llvm/test/Transforms/InstCombine/conditional-negation.ll
new file mode 100644
index 0000000000000..b1b704011ec82
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/conditional-negation.ll
@@ -0,0 +1,276 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -instcombine-infinite-loop-threshold=2 -S | FileCheck %s
+
+; Basic pattern
+define i8 @t0(i8 %x, i1 %cond) {
+; CHECK-LABEL: @t0(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat = sext i1 %cond to i8
+  %sub = add i8 %cond.splat, %x
+  %xor = xor i8 %sub, %cond.splat
+  ret i8 %xor
+}
+define <2 x i8> @t0_vec(<2 x i8> %x, <2 x i1> %cond) {
+; CHECK-LABEL: @t0_vec(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext <2 x i1> [[COND:%.*]] to <2 x i8>
+; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i8> [[COND_SPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i8> [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret <2 x i8> [[XOR]]
+;
+  %cond.splat = sext <2 x i1> %cond to <2 x i8>
+  %sub = add <2 x i8> %cond.splat, %x
+  %xor = xor <2 x i8> %sub, %cond.splat
+  ret <2 x i8> %xor
+}
+
+; Two 
diff erent extensions are fine
+define i8 @t1(i8 %x, i1 %cond) {
+; CHECK-LABEL: @t1(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  %cond.splat1 = sext i1 %cond to i8
+  %sub = add i8 %cond.splat0, %x
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+
+; Two 
diff erent extensions of 
diff erent conditions are not fine
+define i8 @t2(i8 %x, i1 %cond0, i1 %cond1) {
+; CHECK-LABEL: @t2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND0:%.*]] to i8
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND1:%.*]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond0 to i8
+  %cond.splat1 = sext i1 %cond1 to i8
+  %sub = add i8 %cond.splat0, %x
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+
+; Condition must be boolean.
+define i8 @t3(i8 %x, i2 %cond) {
+; CHECK-LABEL: @t3(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext i2 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat = sext i2 %cond to i8
+  %sub = add i8 %cond.splat, %x
+  %xor = xor i8 %sub, %cond.splat
+  ret i8 %xor
+}
+define <2 x i8> @t3_vec(<2 x i8> %x, <2 x i2> %cond) {
+; CHECK-LABEL: @t3_vec(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext <2 x i2> [[COND:%.*]] to <2 x i8>
+; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i8> [[COND_SPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor <2 x i8> [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret <2 x i8> [[XOR]]
+;
+  %cond.splat = sext <2 x i2> %cond to <2 x i8>
+  %sub = add <2 x i8> %cond.splat, %x
+  %xor = xor <2 x i8> %sub, %cond.splat
+  ret <2 x i8> %xor
+}
+
+; add is commutative
+; xor is not commutative here because of complexity ordering
+define i8 @xor.commuted(i1 %cond) {
+; CHECK-LABEL: @xor.commuted(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[X:%.*]] = call i8 @gen.i8()
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[X]], [[COND_SPLAT]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat = sext i1 %cond to i8
+  %x = call i8 @gen.i8()
+  %sub = add i8 %x, %cond.splat
+  %xor = xor i8 %sub, %cond.splat
+  ret i8 %xor
+}
+
+; Extra use tests
+define i8 @extrause01_v1(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause01_v1(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT]])
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat)
+  %sub = add i8 %cond.splat, %x
+  %xor = xor i8 %sub, %cond.splat
+  ret i8 %xor
+}
+define i8 @extrause10_v1(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause10_v1(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT]], [[X:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat = sext i1 %cond to i8
+  %sub = add i8 %cond.splat, %x
+  call void @use.i8(i8 %sub)
+  %xor = xor i8 %sub, %cond.splat
+  ret i8 %xor
+}
+define i8 @extrause11_v1(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause11_v1(
+; CHECK-NEXT:    [[COND_SPLAT:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT]])
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT]], [[X:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat)
+  %sub = add i8 %cond.splat, %x
+  call void @use.i8(i8 %sub)
+  %xor = xor i8 %sub, %cond.splat
+  ret i8 %xor
+}
+
+; Extra use tests with two extensions
+define i8 @extrause001_v2(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause001_v2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT0]])
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat0)
+  %cond.splat1 = sext i1 %cond to i8
+  %sub = add i8 %cond.splat0, %x
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+define i8 @extrause010_v2(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause010_v2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT1]])
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  %cond.splat1 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat1)
+  %sub = add i8 %cond.splat0, %x
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+define i8 @extrause011_v2(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause011_v2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT0]])
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT1]])
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat0)
+  %cond.splat1 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat1)
+  %sub = add i8 %cond.splat0, %x
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+define i8 @extrause100_v2(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause100_v2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  %cond.splat1 = sext i1 %cond to i8
+  %sub = add i8 %cond.splat0, %x
+  call void @use.i8(i8 %sub)
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+define i8 @extrause101_v2(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause101_v2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT0]])
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat0)
+  %cond.splat1 = sext i1 %cond to i8
+  %sub = add i8 %cond.splat0, %x
+  call void @use.i8(i8 %sub)
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+define i8 @extrause110_v2(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause110_v2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT1]])
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  %cond.splat1 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat1)
+  %sub = add i8 %cond.splat0, %x
+  call void @use.i8(i8 %sub)
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+define i8 @extrause111_v2(i8 %x, i1 %cond) {
+; CHECK-LABEL: @extrause111_v2(
+; CHECK-NEXT:    [[COND_SPLAT0:%.*]] = sext i1 [[COND:%.*]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT0]])
+; CHECK-NEXT:    [[COND_SPLAT1:%.*]] = sext i1 [[COND]] to i8
+; CHECK-NEXT:    call void @use.i8(i8 [[COND_SPLAT1]])
+; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[COND_SPLAT0]], [[X:%.*]]
+; CHECK-NEXT:    call void @use.i8(i8 [[SUB]])
+; CHECK-NEXT:    [[XOR:%.*]] = xor i8 [[SUB]], [[COND_SPLAT1]]
+; CHECK-NEXT:    ret i8 [[XOR]]
+;
+  %cond.splat0 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat0)
+  %cond.splat1 = sext i1 %cond to i8
+  call void @use.i8(i8 %cond.splat1)
+  %sub = add i8 %cond.splat0, %x
+  call void @use.i8(i8 %sub)
+  %xor = xor i8 %sub, %cond.splat1
+  ret i8 %xor
+}
+
+declare void @use.i8(i8)
+declare i8 @gen.i8()


        


More information about the llvm-commits mailing list