[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