mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[InstCombine][NFC] PR37603: low bit mask canonicalization tests
Differential Revision: https://reviews.llvm.org/D47427 llvm-svn: 334126
This commit is contained in:
parent
b3af34d70b
commit
2128ec3ad1
316
test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll
Normal file
316
test/Transforms/InstCombine/set-lowbits-mask-canonicalize.ll
Normal file
@ -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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user