[llvm] r334126 - [InstCombine][NFC] PR37603: low bit mask canonicalization tests

Roman Lebedev via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 6 12:38:21 PDT 2018


Author: lebedevri
Date: Wed Jun  6 12:38:21 2018
New Revision: 334126

URL: http://llvm.org/viewvc/llvm-project?rev=334126&view=rev
Log:
[InstCombine][NFC] PR37603: low bit mask canonicalization tests

Differential Revision: https://reviews.llvm.org/D47427

Added:
    llvm/trunk/test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll

Added: llvm/trunk/test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll?rev=334126&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll (added)
+++ llvm/trunk/test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll Wed Jun  6 12:38:21 2018
@@ -0,0 +1,316 @@
+; 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=37603
+
+; Pattern:
+;   (1 << NBits) - 1
+; Should be transformed into:
+;   ~(-(1 << NBits))
+; The `not` may end up being folded into `and`
+
+; ============================================================================ ;
+; Most basic positive tests
+; ============================================================================ ;
+
+; No no-wrap tags on shl
+
+define i32 @shl_add(i32 %NBits) {
+; CHECK-LABEL: @shl_add(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  %ret = add i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_add_nsw(i32 %NBits) {
+; CHECK-LABEL: @shl_add_nsw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  %ret = add nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_add_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_add_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  %ret = add nuw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_add_nsw_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_add_nsw_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  %ret = add nuw nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+; shl is nsw
+
+define i32 @shl_nsw_add(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_add(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nsw i32 1, %NBits
+  %ret = add i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nsw_add_nsw(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_add_nsw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nsw i32 1, %NBits
+  %ret = add nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nsw_add_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_add_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nsw i32 1, %NBits
+  %ret = add nuw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nsw_add_nsw_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_add_nsw_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nsw i32 1, %NBits
+  %ret = add nuw nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+; shl is nuw
+
+define i32 @shl_nuw_add(i32 %NBits) {
+; CHECK-LABEL: @shl_nuw_add(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw i32 1, %NBits
+  %ret = add i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nuw_add_nsw(i32 %NBits) {
+; CHECK-LABEL: @shl_nuw_add_nsw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw i32 1, %NBits
+  %ret = add nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nuw_add_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_nuw_add_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw i32 1, %NBits
+  %ret = add nuw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nuw_add_nsw_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_nuw_add_nsw_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw i32 1, %NBits
+  %ret = add nuw nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+; shl is nuw nsw
+
+define i32 @shl_nsw_nuw_add(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_nuw_add(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw nsw i32 1, %NBits
+  %ret = add i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nsw_nuw_add_nsw(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_nuw_add_nsw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw nsw i32 1, %NBits
+  %ret = add nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nsw_nuw_add_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_nuw_add_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw nsw i32 1, %NBits
+  %ret = add nuw i32 %setbit, -1
+  ret i32 %ret
+}
+
+define i32 @shl_nsw_nuw_add_nsw_nuw(i32 %NBits) {
+; CHECK-LABEL: @shl_nsw_nuw_add_nsw_nuw(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl nuw nsw i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add nuw nsw i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl nuw nsw i32 1, %NBits
+  %ret = add nuw nsw i32 %setbit, -1
+  ret i32 %ret
+}
+
+; ============================================================================ ;
+; Vectors
+; ============================================================================ ;
+
+define <2 x i32> @shl_add_vec(<2 x i32> %NBits) {
+; CHECK-LABEL: @shl_add_vec(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl <2 x i32> <i32 1, i32 1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add <2 x i32> [[SETBIT]], <i32 -1, i32 -1>
+; CHECK-NEXT:    ret <2 x i32> [[RET]]
+;
+  %setbit = shl <2 x i32> <i32 1, i32 1>, %NBits
+  %ret = add <2 x i32> %setbit, <i32 -1, i32 -1>
+  ret <2 x i32> %ret
+}
+
+define <3 x i32> @shl_add_vec_undef0(<3 x i32> %NBits) {
+; CHECK-LABEL: @shl_add_vec_undef0(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl <3 x i32> <i32 1, i32 undef, i32 1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add <3 x i32> [[SETBIT]], <i32 -1, i32 -1, i32 -1>
+; CHECK-NEXT:    ret <3 x i32> [[RET]]
+;
+  %setbit = shl <3 x i32> <i32 1, i32 undef, i32 1>, %NBits
+  %ret = add <3 x i32> %setbit, <i32 -1, i32 -1, i32 -1>
+  ret <3 x i32> %ret
+}
+
+define <3 x i32> @shl_add_vec_undef1(<3 x i32> %NBits) {
+; CHECK-LABEL: @shl_add_vec_undef1(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl <3 x i32> <i32 1, i32 1, i32 1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add <3 x i32> [[SETBIT]], <i32 -1, i32 undef, i32 -1>
+; CHECK-NEXT:    ret <3 x i32> [[RET]]
+;
+  %setbit = shl <3 x i32> <i32 1, i32 1, i32 1>, %NBits
+  %ret = add <3 x i32> %setbit, <i32 -1, i32 undef, i32 -1>
+  ret <3 x i32> %ret
+}
+
+define <3 x i32> @shl_add_vec_undef2(<3 x i32> %NBits) {
+; CHECK-LABEL: @shl_add_vec_undef2(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl <3 x i32> <i32 1, i32 undef, i32 1>, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add <3 x i32> [[SETBIT]], <i32 -1, i32 undef, i32 -1>
+; CHECK-NEXT:    ret <3 x i32> [[RET]]
+;
+  %setbit = shl <3 x i32> <i32 1, i32 undef, i32 1>, %NBits
+  %ret = add <3 x i32> %setbit, <i32 -1, i32 undef, i32 -1>
+  ret <3 x i32> %ret
+}
+
+; ============================================================================ ;
+; Negative tests. Should not be folded.
+; ============================================================================ ;
+
+declare void @use32(i32)
+
+; One use only.
+define i32 @bad_oneuse0(i32 %NBits) {
+; CHECK-LABEL: @bad_oneuse0(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    call void @use32(i32 [[SETBIT]])
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  call void @use32(i32 %setbit)
+  %ret = add i32 %setbit, -1
+  ret i32 %ret
+}
+
+; shift base is not `1` constant
+
+define i32 @bad_shl(i32 %base, i32 %NBits) {
+; CHECK-LABEL: @bad_shl(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 [[BASE:%.*]], [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 %base, %NBits ; %base instead of 1
+  %ret = add i32 %setbit, -1
+  ret i32 %ret
+}
+
+; Second `add` operand is not `-1` constant
+
+define i32 @bad_add0(i32 %NBits, i32 %addop2) {
+; CHECK-LABEL: @bad_add0(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], [[ADDOP2:%.*]]
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  %ret = add i32 %setbit, %addop2
+  ret i32 %ret
+}
+
+; Bad add constant
+
+define i32 @bad_add1(i32 %NBits) {
+; CHECK-LABEL: @bad_add1(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], 1
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  %ret = add i32 %setbit, 1 ; not -1
+  ret i32 %ret
+}
+
+define i32 @bad_add2(i32 %NBits) {
+; CHECK-LABEL: @bad_add2(
+; CHECK-NEXT:    [[SETBIT:%.*]] = shl i32 1, [[NBITS:%.*]]
+; CHECK-NEXT:    [[RET:%.*]] = add i32 [[SETBIT]], -2
+; CHECK-NEXT:    ret i32 [[RET]]
+;
+  %setbit = shl i32 1, %NBits
+  %ret = add i32 %setbit, -2 ; not -1
+  ret i32 %ret
+}




More information about the llvm-commits mailing list