[llvm] r338967 - [NFC][InstCombine] Add tests for sinking 'not' into 'xor' (PR38446)
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 5 03:15:04 PDT 2018
Author: lebedevri
Date: Sun Aug 5 03:15:04 2018
New Revision: 338967
URL: http://llvm.org/viewvc/llvm-project?rev=338967&view=rev
Log:
[NFC][InstCombine] Add tests for sinking 'not' into 'xor' (PR38446)
https://rise4fun.com/Alive/IT3
Comes up in the [most ugliest] signed int -> signed char case of
-fsanitize=implicit-conversion (https://reviews.llvm.org/D50250)
Not sure if we want to do it always, or only when it is free to invert.
Added:
llvm/trunk/test/Transforms/InstCombine/demorgan-sink-not-into-xor.ll
Added: llvm/trunk/test/Transforms/InstCombine/demorgan-sink-not-into-xor.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/demorgan-sink-not-into-xor.ll?rev=338967&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/demorgan-sink-not-into-xor.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/demorgan-sink-not-into-xor.ll Sun Aug 5 03:15:04 2018
@@ -0,0 +1,170 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; https://bugs.llvm.org/show_bug.cgi?id=38446
+
+; Pattern:
+; ~(x ^ y)
+; Should be transformed into:
+; (~x) ^ y
+; or into
+; x ^ (~y)
+
+; While -reassociate does handle this simple pattern, it does not handle
+; the more complicated motivating pattern.
+
+; ============================================================================ ;
+; Basic positive tests
+; ============================================================================ ;
+
+; Just fold it into the first operand.
+define i32 @positive(i32 %x, i32 %y) {
+; CHECK-LABEL: @positive(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[TMP2]]
+;
+ %tmp1 = xor i32 %x, %y
+ %tmp2 = xor i32 %tmp1, -1
+ ret i32 %tmp2
+}
+
+declare i32 @gen32()
+
+; If the [second] operand is easily-invertible, fold into it.
+declare i1 @gen1()
+
+define i1 @positive_easyinvert(i8 %y) {
+; CHECK-LABEL: @positive_easyinvert(
+; CHECK-NEXT: [[TMP1:%.*]] = call i1 @gen1()
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[Y:%.*]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true
+; CHECK-NEXT: ret i1 [[TMP4]]
+;
+ %tmp1 = call i1 @gen1()
+ %tmp2 = icmp slt i8 %y, 0
+ %tmp3 = xor i1 %tmp1, %tmp2
+ %tmp4 = xor i1 %tmp3, true
+ ret i1 %tmp4
+}
+
+; ============================================================================ ;
+; Vector tests
+; ============================================================================ ;
+
+define <2 x i32> @positive_vec(<2 x i32> %x, <2 x i32> %y) {
+; CHECK-LABEL: @positive_vec(
+; CHECK-NEXT: [[TMP1:%.*]] = xor <2 x i32> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = xor <2 x i32> [[TMP1]], <i32 -1, i32 -1>
+; CHECK-NEXT: ret <2 x i32> [[TMP2]]
+;
+ %tmp1 = xor <2 x i32> %x, %y
+ %tmp2 = xor <2 x i32> %tmp1, <i32 -1, i32 -1>
+ ret <2 x i32> %tmp2
+}
+
+define <3 x i32> @positive_vec_undef(<3 x i32> %x, <3 x i32> %y) {
+; CHECK-LABEL: @positive_vec_undef(
+; CHECK-NEXT: [[TMP1:%.*]] = xor <3 x i32> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = xor <3 x i32> [[TMP1]], <i32 -1, i32 undef, i32 -1>
+; CHECK-NEXT: ret <3 x i32> [[TMP2]]
+;
+ %tmp1 = xor <3 x i32> %x, %y
+ %tmp2 = xor <3 x i32> %tmp1, <i32 -1, i32 undef, i32 -1>
+ ret <3 x i32> %tmp2
+}
+
+; ============================================================================ ;
+; One-use tests.
+; ============================================================================ ;
+
+declare void @use32(i32)
+
+define i32 @oneuse_0(i32 %x, i32 %y) {
+; CHECK-LABEL: @oneuse_0(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: call void @use32(i32 [[TMP1]])
+; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], -1
+; CHECK-NEXT: ret i32 [[TMP2]]
+;
+ %tmp1 = xor i32 %x, %y
+ call void @use32(i32 %tmp1)
+ %tmp2 = xor i32 %tmp1, -1
+ ret i32 %tmp2
+}
+
+; ============================================================================ ;
+; One-use tests with easily-invertible operand.
+; ============================================================================ ;
+
+declare void @use1(i1)
+
+define i1 @oneuse_easyinvert_0(i8 %y) {
+; CHECK-LABEL: @oneuse_easyinvert_0(
+; CHECK-NEXT: [[TMP1:%.*]] = call i1 @gen1()
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[Y:%.*]], 0
+; CHECK-NEXT: call void @use1(i1 [[TMP2]])
+; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true
+; CHECK-NEXT: ret i1 [[TMP4]]
+;
+ %tmp1 = call i1 @gen1()
+ %tmp2 = icmp slt i8 %y, 0
+ call void @use1(i1 %tmp2)
+ %tmp3 = xor i1 %tmp1, %tmp2
+ %tmp4 = xor i1 %tmp3, true
+ ret i1 %tmp4
+}
+
+define i1 @oneuse_easyinvert_1(i8 %y) {
+; CHECK-LABEL: @oneuse_easyinvert_1(
+; CHECK-NEXT: [[TMP1:%.*]] = call i1 @gen1()
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[Y:%.*]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: call void @use1(i1 [[TMP3]])
+; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true
+; CHECK-NEXT: ret i1 [[TMP4]]
+;
+ %tmp1 = call i1 @gen1()
+ %tmp2 = icmp slt i8 %y, 0
+ %tmp3 = xor i1 %tmp1, %tmp2
+ call void @use1(i1 %tmp3)
+ %tmp4 = xor i1 %tmp3, true
+ ret i1 %tmp4
+}
+
+define i1 @oneuse_easyinvert_2(i8 %y) {
+; CHECK-LABEL: @oneuse_easyinvert_2(
+; CHECK-NEXT: [[TMP1:%.*]] = call i1 @gen1()
+; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i8 [[Y:%.*]], 0
+; CHECK-NEXT: call void @use1(i1 [[TMP2]])
+; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP1]], [[TMP2]]
+; CHECK-NEXT: call void @use1(i1 [[TMP3]])
+; CHECK-NEXT: [[TMP4:%.*]] = xor i1 [[TMP3]], true
+; CHECK-NEXT: ret i1 [[TMP4]]
+;
+ %tmp1 = call i1 @gen1()
+ %tmp2 = icmp slt i8 %y, 0
+ call void @use1(i1 %tmp2)
+ %tmp3 = xor i1 %tmp1, %tmp2
+ call void @use1(i1 %tmp3)
+ %tmp4 = xor i1 %tmp3, true
+ ret i1 %tmp4
+}
+
+; ============================================================================ ;
+; Negative tests
+; ============================================================================ ;
+
+; It has to be 'not'.
+define i32 @negative(i32 %x, i32 %y) {
+; CHECK-LABEL: @negative(
+; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 1
+; CHECK-NEXT: ret i32 [[TMP2]]
+;
+ %tmp1 = xor i32 %x, %y
+ %tmp2 = xor i32 %tmp1, 1 ; not -1
+ ret i32 %tmp2
+}
More information about the llvm-commits
mailing list