2016-05-02 23:32:10 +08:00
|
|
|
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
2009-10-12 06:36:59 +08:00
|
|
|
; RUN: opt < %s -instcombine -S | FileCheck %s
|
2002-05-06 13:43:36 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test1(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test1(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 %A
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = shl i32 %A, 0
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %B
|
2002-05-06 13:43:36 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test2(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test2(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 0
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%shift.upgrd.1 = zext i8 %A to i32
|
|
|
|
%B = shl i32 0, %shift.upgrd.1
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %B
|
2002-05-06 13:43:36 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test3(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test3(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 %A
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = ashr i32 %A, 0
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %B
|
2002-05-06 13:43:36 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test4(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test4(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 0
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%shift.upgrd.2 = zext i8 %A to i32
|
|
|
|
%B = ashr i32 0, %shift.upgrd.2
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %B
|
2002-05-06 13:43:36 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test5(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test5(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 undef
|
|
|
|
;
|
|
|
|
%B = lshr i32 %A, 32 ;; shift all bits out
|
|
|
|
ret i32 %B
|
2002-05-06 13:43:36 +08:00
|
|
|
}
|
|
|
|
|
2014-04-15 05:50:37 +08:00
|
|
|
define <4 x i32> @test5_splat_vector(<4 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test5_splat_vector(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret <4 x i32> undef
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%B = lshr <4 x i32> %A, <i32 32, i32 32, i32 32, i32 32> ;; shift all bits out
|
|
|
|
ret <4 x i32> %B
|
|
|
|
}
|
|
|
|
|
|
|
|
define <4 x i32> @test5_zero_vector(<4 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test5_zero_vector(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret <4 x i32> %A
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%B = lshr <4 x i32> %A, zeroinitializer
|
|
|
|
ret <4 x i32> %B
|
|
|
|
}
|
|
|
|
|
|
|
|
define <4 x i32> @test5_non_splat_vector(<4 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test5_non_splat_vector(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = lshr <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
|
|
|
|
; CHECK-NEXT: ret <4 x i32> [[B]]
|
|
|
|
;
|
2014-12-08 17:40:43 +08:00
|
|
|
%B = lshr <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
|
2014-04-15 05:50:37 +08:00
|
|
|
ret <4 x i32> %B
|
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test5a(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test5a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 undef
|
|
|
|
;
|
|
|
|
%B = shl i32 %A, 32 ;; shift all bits out
|
|
|
|
ret i32 %B
|
2003-03-11 03:16:20 +08:00
|
|
|
}
|
|
|
|
|
2014-04-15 05:50:37 +08:00
|
|
|
define <4 x i32> @test5a_splat_vector(<4 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test5a_splat_vector(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret <4 x i32> undef
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%B = shl <4 x i32> %A, <i32 32, i32 32, i32 32, i32 32> ;; shift all bits out
|
|
|
|
ret <4 x i32> %B
|
|
|
|
}
|
|
|
|
|
|
|
|
define <4 x i32> @test5a_non_splat_vector(<4 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test5a_non_splat_vector(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
|
|
|
|
; CHECK-NEXT: ret <4 x i32> [[B]]
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%B = shl <4 x i32> %A, <i32 32, i32 1, i32 2, i32 3>
|
|
|
|
ret <4 x i32> %B
|
|
|
|
}
|
|
|
|
|
2011-01-14 08:37:45 +08:00
|
|
|
define i32 @test5b() {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test5b(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 0
|
|
|
|
;
|
|
|
|
%B = ashr i32 undef, 2 ;; top two bits must be equal, so not undef
|
|
|
|
ret i32 %B
|
2011-01-14 08:37:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test5b2(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test5b2(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 0
|
|
|
|
;
|
|
|
|
%B = ashr i32 undef, %A ;; top %A bits must be equal, so not undef
|
|
|
|
ret i32 %B
|
2011-01-14 08:37:45 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test6(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test6(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = mul i32 %A, 6
|
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
|
|
|
%B = shl i32 %A, 1 ;; convert to an mul instruction
|
|
|
|
%C = mul i32 %B, 3
|
|
|
|
ret i32 %C
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test6a(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test6a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = mul i32 %A, 6
|
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
|
|
|
%B = mul i32 %A, 3
|
|
|
|
%C = shl i32 %B, 1 ;; convert to an mul instruction
|
|
|
|
ret i32 %C
|
2002-09-11 07:03:10 +08:00
|
|
|
}
|
2002-10-09 00:10:35 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test7(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test7(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 -1
|
|
|
|
;
|
|
|
|
%shift.upgrd.3 = zext i8 %A to i32
|
|
|
|
%B = ashr i32 -1, %shift.upgrd.3 ;; Always equal to -1
|
|
|
|
ret i32 %B
|
2002-10-09 00:10:35 +08:00
|
|
|
}
|
2003-03-11 03:16:20 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
;; (A << 5) << 3 === A << 8 == 0
|
|
|
|
define i8 @test8(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test8(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i8 0
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = shl i8 %A, 5
|
|
|
|
%C = shl i8 %B, 3
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %C
|
2003-03-11 03:16:20 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
;; (A << 7) >> 7 === A & 1
|
|
|
|
define i8 @test9(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test9(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = and i8 %A, 1
|
|
|
|
; CHECK-NEXT: ret i8 [[B]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = shl i8 %A, 7
|
|
|
|
%C = lshr i8 %B, 7
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %C
|
2003-03-11 03:16:20 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
;; (A >> 7) << 7 === A & 128
|
2017-01-16 07:45:03 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i8 @test10(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test10(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = and i8 %A, -128
|
|
|
|
; CHECK-NEXT: ret i8 [[B]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = lshr i8 %A, 7
|
|
|
|
%C = shl i8 %B, 7
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %C
|
2003-03-11 03:16:20 +08:00
|
|
|
}
|
|
|
|
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
;; Allow the simplification when the lshr shift is exact.
|
|
|
|
define i8 @test10a(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test10a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i8 %A
|
|
|
|
;
|
|
|
|
%B = lshr exact i8 %A, 7
|
|
|
|
%C = shl i8 %B, 7
|
|
|
|
ret i8 %C
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
;; This transformation is deferred to DAGCombine:
|
2008-03-01 17:15:35 +08:00
|
|
|
;; (A >> 3) << 4 === (A & 0x1F) << 1
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
;; The shl may be valuable to scalar evolution.
|
2008-03-01 17:15:35 +08:00
|
|
|
define i8 @test11(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test11(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[A:%.*]] = mul i8 %A, 3
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = lshr i8 [[A]], 3
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = shl i8 [[B]], 4
|
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%a = mul i8 %A, 3
|
|
|
|
%B = lshr i8 %a, 3
|
|
|
|
%C = shl i8 %B, 4
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %C
|
2003-03-11 03:16:20 +08:00
|
|
|
}
|
|
|
|
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
;; Allow the simplification in InstCombine when the lshr shift is exact.
|
|
|
|
define i8 @test11a(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test11a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = mul i8 %A, 6
|
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
|
|
|
%a = mul i8 %A, 3
|
|
|
|
%B = lshr exact i8 %a, 3
|
|
|
|
%C = shl i8 %B, 4
|
|
|
|
ret i8 %C
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
;; This is deferred to DAGCombine unless %B is single-use.
|
2008-03-01 17:15:35 +08:00
|
|
|
;; (A >> 8) << 8 === A & -256
|
|
|
|
define i32 @test12(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test12(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B1:%.*]] = and i32 %A, -256
|
|
|
|
; CHECK-NEXT: ret i32 [[B1]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = ashr i32 %A, 8
|
|
|
|
%C = shl i32 %B, 8
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %C
|
2003-07-25 02:38:09 +08:00
|
|
|
}
|
|
|
|
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
;; This transformation is deferred to DAGCombine:
|
2008-03-01 17:15:35 +08:00
|
|
|
;; (A >> 3) << 4 === (A & -8) * 2
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
;; The shl may be valuable to scalar evolution.
|
2008-03-01 17:15:35 +08:00
|
|
|
define i8 @test13(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test13(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[A:%.*]] = mul i8 %A, 3
|
|
|
|
; CHECK-NEXT: [[B1:%.*]] = lshr i8 [[A]], 3
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = shl i8 [[B1]], 4
|
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%a = mul i8 %A, 3
|
|
|
|
%B = ashr i8 %a, 3
|
|
|
|
%C = shl i8 %B, 4
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %C
|
2003-07-25 02:38:09 +08:00
|
|
|
}
|
2003-08-13 05:20:49 +08:00
|
|
|
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
define i8 @test13a(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test13a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = mul i8 %A, 6
|
|
|
|
; CHECK-NEXT: ret i8 [[C]]
|
|
|
|
;
|
|
|
|
%a = mul i8 %A, 3
|
|
|
|
%B = ashr exact i8 %a, 3
|
|
|
|
%C = shl i8 %B, 4
|
|
|
|
ret i8 %C
|
Reapply r155136 after fixing PR12599.
Original commit message:
Defer some shl transforms to DAGCombine.
The shl instruction is used to represent multiplication by a constant
power of two as well as bitwise left shifts. Some InstCombine
transformations would turn an shl instruction into a bit mask operation,
making it difficult for later analysis passes to recognize the
constsnt multiplication.
Disable those shl transformations, deferring them to DAGCombine time.
An 'shl X, C' instruction is now treated mostly the same was as 'mul X, C'.
These transformations are deferred:
(X >>? C) << C --> X & (-1 << C) (When X >> C has multiple uses)
(X >>? C1) << C2 --> X << (C2-C1) & (-1 << C2) (When C2 > C1)
(X >>? C1) << C2 --> X >>? (C1-C2) & (-1 << C2) (When C1 > C2)
The corresponding exact transformations are preserved, just like
div-exact + mul:
(X >>?,exact C) << C --> X
(X >>?,exact C1) << C2 --> X << (C2-C1)
(X >>?,exact C1) << C2 --> X >>?,exact (C1-C2)
The disabled transformations could also prevent the instruction selector
from recognizing rotate patterns in hash functions and cryptographic
primitives. I have a test case for that, but it is too fragile.
llvm-svn: 155362
2012-04-24 01:39:52 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
;; D = ((B | 1234) << 4) === ((B << 4)|(1234 << 4)
|
|
|
|
define i32 @test14(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test14(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = and i32 %A, -19760
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = or i32 [[B]], 19744
|
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = lshr i32 %A, 4
|
|
|
|
%C = or i32 %B, 1234
|
|
|
|
%D = shl i32 %C, 4
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %D
|
2003-08-13 05:20:49 +08:00
|
|
|
}
|
2008-03-01 17:15:35 +08:00
|
|
|
|
|
|
|
;; D = ((B | 1234) << 4) === ((B << 4)|(1234 << 4)
|
|
|
|
define i32 @test14a(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test14a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = and i32 %A, 77
|
|
|
|
; CHECK-NEXT: ret i32 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = shl i32 %A, 4
|
|
|
|
%C = and i32 %B, 1234
|
|
|
|
%D = lshr i32 %C, 4
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %D
|
2003-08-13 05:20:49 +08:00
|
|
|
}
|
2004-04-10 07:47:24 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test15(i1 %C) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test15(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[A:%.*]] = select i1 %C, i32 12, i32 4
|
|
|
|
; CHECK-NEXT: ret i32 [[A]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%A = select i1 %C, i32 3, i32 1
|
|
|
|
%V = shl i32 %A, 2
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %V
|
2004-04-10 07:47:24 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test15a(i1 %C) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test15a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[V:%.*]] = select i1 %C, i32 512, i32 128
|
|
|
|
; CHECK-NEXT: ret i32 [[V]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%A = select i1 %C, i8 3, i8 1
|
|
|
|
%shift.upgrd.4 = zext i8 %A to i32
|
|
|
|
%V = shl i32 64, %shift.upgrd.4
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %V
|
2004-04-10 07:47:24 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i1 @test16(i32 %X) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test16(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[TMP_6:%.*]] = and i32 %X, 16
|
|
|
|
; CHECK-NEXT: [[TMP_7:%.*]] = icmp ne i32 [[TMP_6]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[TMP_7]]
|
|
|
|
;
|
|
|
|
%tmp.3 = ashr i32 %X, 4
|
|
|
|
%tmp.6 = and i32 %tmp.3, 1
|
|
|
|
%tmp.7 = icmp ne i32 %tmp.6, 0
|
|
|
|
ret i1 %tmp.7
|
2004-05-25 14:30:49 +08:00
|
|
|
}
|
2004-09-28 00:21:26 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i1 @test17(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test17(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B_MASK:%.*]] = and i32 %A, -8
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[B_MASK]], 9872
|
|
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = lshr i32 %A, 3
|
|
|
|
%C = icmp eq i32 %B, 1234
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i1 %C
|
2004-09-28 00:21:26 +08:00
|
|
|
}
|
|
|
|
|
2016-08-16 02:26:56 +08:00
|
|
|
define <2 x i1> @test17vec(<2 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test17vec(
|
2016-08-25 06:22:06 +08:00
|
|
|
; CHECK-NEXT: [[B_MASK:%.*]] = and <2 x i32> %A, <i32 -8, i32 -8>
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp eq <2 x i32> [[B_MASK]], <i32 9872, i32 9872>
|
2016-08-16 02:26:56 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[C]]
|
|
|
|
;
|
|
|
|
%B = lshr <2 x i32> %A, <i32 3, i32 3>
|
|
|
|
%C = icmp eq <2 x i32> %B, <i32 1234, i32 1234>
|
|
|
|
ret <2 x i1> %C
|
|
|
|
}
|
2008-03-01 17:15:35 +08:00
|
|
|
|
|
|
|
define i1 @test18(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test18(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i1 false
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = lshr i8 %A, 7
|
2016-05-02 23:32:10 +08:00
|
|
|
;; false
|
2016-08-16 02:32:50 +08:00
|
|
|
%C = icmp eq i8 %B, 123
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i1 %C
|
2004-09-28 00:21:26 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i1 @test19(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test19(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 %A, 4
|
|
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = ashr i32 %A, 2
|
2016-05-02 23:32:10 +08:00
|
|
|
;; (X & -4) == 0
|
2016-08-16 02:32:50 +08:00
|
|
|
%C = icmp eq i32 %B, 0
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i1 %C
|
2004-09-28 00:21:26 +08:00
|
|
|
}
|
|
|
|
|
2016-08-16 02:26:56 +08:00
|
|
|
define <2 x i1> @test19vec(<2 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test19vec(
|
2016-08-25 06:22:06 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ult <2 x i32> %A, <i32 4, i32 4>
|
2016-08-16 02:26:56 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[C]]
|
|
|
|
;
|
|
|
|
%B = ashr <2 x i32> %A, <i32 2, i32 2>
|
|
|
|
%C = icmp eq <2 x i32> %B, zeroinitializer
|
|
|
|
ret <2 x i1> %C
|
|
|
|
}
|
2008-03-01 17:15:35 +08:00
|
|
|
|
2016-08-15 06:29:27 +08:00
|
|
|
;; X >u ~4
|
2008-03-01 17:15:35 +08:00
|
|
|
define i1 @test19a(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test19a(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 %A, -5
|
|
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
|
|
;
|
2016-08-15 06:29:27 +08:00
|
|
|
%B = ashr i32 %A, 2
|
|
|
|
%C = icmp eq i32 %B, -1
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i1 %C
|
2004-09-28 00:21:26 +08:00
|
|
|
}
|
|
|
|
|
2016-08-15 06:29:27 +08:00
|
|
|
define <2 x i1> @test19a_vec(<2 x i32> %A) {
|
|
|
|
; CHECK-LABEL: @test19a_vec(
|
2016-08-29 02:18:00 +08:00
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp ugt <2 x i32> %A, <i32 -5, i32 -5>
|
2016-08-15 06:29:27 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[C]]
|
|
|
|
;
|
|
|
|
%B = ashr <2 x i32> %A, <i32 2, i32 2>
|
|
|
|
%C = icmp eq <2 x i32> %B, <i32 -1, i32 -1>
|
|
|
|
ret <2 x i1> %C
|
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i1 @test20(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test20(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i1 false
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = ashr i8 %A, 7
|
2016-05-02 23:32:10 +08:00
|
|
|
;; false
|
2016-08-16 02:32:50 +08:00
|
|
|
%C = icmp eq i8 %B, 123
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i1 %C
|
2004-09-28 00:21:26 +08:00
|
|
|
}
|
2004-09-29 02:18:35 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i1 @test21(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test21(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B_MASK:%.*]] = and i8 %A, 15
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B_MASK]], 8
|
|
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = shl i8 %A, 4
|
|
|
|
%C = icmp eq i8 %B, -128
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i1 %C
|
2004-09-29 02:18:35 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i1 @test22(i8 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test22(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B_MASK:%.*]] = and i8 %A, 15
|
|
|
|
; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[B_MASK]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[C]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = shl i8 %A, 4
|
|
|
|
%C = icmp eq i8 %B, 0
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i1 %C
|
2004-09-29 02:18:35 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i8 @test23(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test23(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[D:%.*]] = trunc i32 %A to i8
|
|
|
|
; CHECK-NEXT: ret i8 [[D]]
|
|
|
|
;
|
|
|
|
;; casts not needed
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = shl i32 %A, 24
|
|
|
|
%C = ashr i32 %B, 24
|
|
|
|
%D = trunc i32 %C to i8
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %D
|
2005-05-06 12:11:32 +08:00
|
|
|
}
|
2005-05-09 01:31:24 +08:00
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i8 @test24(i8 %X) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test24(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[Z:%.*]] = and i8 %X, 3
|
|
|
|
; CHECK-NEXT: ret i8 [[Z]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%Y = and i8 %X, -5
|
|
|
|
%Z = shl i8 %Y, 5
|
|
|
|
%Q = ashr i8 %Z, 5
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %Q
|
2005-05-09 01:31:24 +08:00
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
define i32 @test25(i32 %tmp.2, i32 %AA) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test25(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[TMP_3:%.*]] = and i32 %tmp.2, -131072
|
|
|
|
; CHECK-NEXT: [[X2:%.*]] = add i32 [[TMP_3]], %AA
|
|
|
|
; CHECK-NEXT: [[TMP_6:%.*]] = and i32 [[X2]], -131072
|
|
|
|
; CHECK-NEXT: ret i32 [[TMP_6]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%x = lshr i32 %AA, 17
|
|
|
|
%tmp.3 = lshr i32 %tmp.2, 17
|
|
|
|
%tmp.5 = add i32 %tmp.3, %x
|
|
|
|
%tmp.6 = shl i32 %tmp.5, 17
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %tmp.6
|
2005-09-18 13:10:39 +08:00
|
|
|
}
|
|
|
|
|
2014-04-15 05:50:37 +08:00
|
|
|
define <2 x i32> @test25_vector(<2 x i32> %tmp.2, <2 x i32> %AA) {
|
|
|
|
; CHECK-LABEL: @test25_vector(
|
2017-01-17 03:35:45 +08:00
|
|
|
; CHECK-NEXT: [[TMP_3:%.*]] = and <2 x i32> %tmp.2, <i32 -131072, i32 -131072>
|
|
|
|
; CHECK-NEXT: [[X2:%.*]] = add <2 x i32> [[TMP_3]], %AA
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[TMP_6:%.*]] = and <2 x i32> [[X2]], <i32 -131072, i32 -131072>
|
|
|
|
; CHECK-NEXT: ret <2 x i32> [[TMP_6]]
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%x = lshr <2 x i32> %AA, <i32 17, i32 17>
|
|
|
|
%tmp.3 = lshr <2 x i32> %tmp.2, <i32 17, i32 17>
|
|
|
|
%tmp.5 = add <2 x i32> %tmp.3, %x
|
|
|
|
%tmp.6 = shl <2 x i32> %tmp.5, <i32 17, i32 17>
|
|
|
|
ret <2 x i32> %tmp.6
|
|
|
|
}
|
|
|
|
|
2008-03-01 17:15:35 +08:00
|
|
|
;; handle casts between shifts.
|
|
|
|
define i32 @test26(i32 %A) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test26(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = and i32 %A, -2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
2016-08-16 02:32:50 +08:00
|
|
|
%B = lshr i32 %A, 1
|
|
|
|
%C = bitcast i32 %B to i32
|
|
|
|
%D = shl i32 %C, 1
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i32 %D
|
2006-01-06 15:48:28 +08:00
|
|
|
}
|
2009-03-25 02:15:30 +08:00
|
|
|
|
|
|
|
|
|
|
|
define i1 @test27(i32 %x) nounwind {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test27(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = and i32 %x, 8
|
|
|
|
; CHECK-NEXT: [[Z:%.*]] = icmp ne i32 [[TMP1]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[Z]]
|
|
|
|
;
|
2009-03-25 02:15:30 +08:00
|
|
|
%y = lshr i32 %x, 3
|
|
|
|
%z = trunc i32 %y to i1
|
|
|
|
ret i1 %z
|
|
|
|
}
|
2014-04-14 15:03:13 +08:00
|
|
|
|
2016-08-16 02:35:44 +08:00
|
|
|
define i1 @test28(i8 %x) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test28(
|
2016-08-16 02:35:44 +08:00
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i8 %x, 0
|
|
|
|
; CHECK-NEXT: ret i1 [[CMP]]
|
2016-05-02 23:32:10 +08:00
|
|
|
;
|
2016-08-16 02:35:44 +08:00
|
|
|
%shr = lshr i8 %x, 7
|
|
|
|
%cmp = icmp ne i8 %shr, 0
|
|
|
|
ret i1 %cmp
|
2009-10-12 06:39:58 +08:00
|
|
|
}
|
|
|
|
|
2016-08-16 02:39:54 +08:00
|
|
|
define <2 x i1> @test28vec(<2 x i8> %x) {
|
|
|
|
; CHECK-LABEL: @test28vec(
|
2016-08-25 06:22:06 +08:00
|
|
|
; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i8> %x, zeroinitializer
|
2016-08-16 02:39:54 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[CMP]]
|
|
|
|
;
|
|
|
|
%shr = lshr <2 x i8> %x, <i8 7, i8 7>
|
|
|
|
%cmp = icmp ne <2 x i8> %shr, zeroinitializer
|
|
|
|
ret <2 x i1> %cmp
|
|
|
|
}
|
|
|
|
|
2009-10-12 06:39:58 +08:00
|
|
|
define i8 @test28a(i8 %x, i8 %y) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test28a(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr i8 %x, 7
|
|
|
|
; CHECK-NEXT: [[COND1:%.*]] = icmp eq i8 [[TMP1]], 0
|
|
|
|
; CHECK-NEXT: br i1 [[COND1]], label %bb2, label %bb1
|
|
|
|
; CHECK: bb1:
|
|
|
|
; CHECK-NEXT: ret i8 [[TMP1]]
|
|
|
|
; CHECK: bb2:
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[TMP1]], %y
|
|
|
|
; CHECK-NEXT: ret i8 [[TMP2]]
|
|
|
|
;
|
2009-10-12 06:39:58 +08:00
|
|
|
entry:
|
|
|
|
; This shouldn't be transformed.
|
2016-05-02 23:32:10 +08:00
|
|
|
%tmp1 = lshr i8 %x, 7
|
|
|
|
%cond1 = icmp ne i8 %tmp1, 0
|
|
|
|
br i1 %cond1, label %bb1, label %bb2
|
2009-10-12 06:39:58 +08:00
|
|
|
bb1:
|
2016-05-02 23:32:10 +08:00
|
|
|
ret i8 %tmp1
|
2009-10-12 06:39:58 +08:00
|
|
|
bb2:
|
2016-05-02 23:32:10 +08:00
|
|
|
%tmp2 = add i8 %tmp1, %y
|
|
|
|
ret i8 %tmp2
|
2009-10-12 06:39:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-28 04:42:10 +08:00
|
|
|
define i32 @test29(i64 %d18) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test29(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP916:%.*]] = lshr i64 %d18, 63
|
|
|
|
; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP916]] to i32
|
|
|
|
; CHECK-NEXT: ret i32 [[TMP10]]
|
|
|
|
;
|
|
|
|
entry:
|
|
|
|
%tmp916 = lshr i64 %d18, 32
|
|
|
|
%tmp917 = trunc i64 %tmp916 to i32
|
|
|
|
%tmp10 = lshr i32 %tmp917, 31
|
|
|
|
ret i32 %tmp10
|
2010-08-28 04:42:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-08-28 04:44:45 +08:00
|
|
|
define i32 @test30(i32 %A, i32 %B, i32 %C) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test30(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[X1:%.*]] = and i32 %A, %B
|
|
|
|
; CHECK-NEXT: [[Z:%.*]] = shl i32 [[X1]], %C
|
|
|
|
; CHECK-NEXT: ret i32 [[Z]]
|
|
|
|
;
|
|
|
|
%X = shl i32 %A, %C
|
|
|
|
%Y = shl i32 %B, %C
|
|
|
|
%Z = and i32 %X, %Y
|
|
|
|
ret i32 %Z
|
2010-08-28 04:44:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test31(i32 %A, i32 %B, i32 %C) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test31(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[X1:%.*]] = or i32 %A, %B
|
|
|
|
; CHECK-NEXT: [[Z:%.*]] = lshr i32 [[X1]], %C
|
|
|
|
; CHECK-NEXT: ret i32 [[Z]]
|
|
|
|
;
|
|
|
|
%X = lshr i32 %A, %C
|
|
|
|
%Y = lshr i32 %B, %C
|
|
|
|
%Z = or i32 %X, %Y
|
|
|
|
ret i32 %Z
|
2010-08-28 04:44:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test32(i32 %A, i32 %B, i32 %C) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test32(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[X1:%.*]] = xor i32 %A, %B
|
|
|
|
; CHECK-NEXT: [[Z:%.*]] = ashr i32 [[X1]], %C
|
|
|
|
; CHECK-NEXT: ret i32 [[Z]]
|
|
|
|
;
|
|
|
|
%X = ashr i32 %A, %C
|
|
|
|
%Y = ashr i32 %B, %C
|
|
|
|
%Z = xor i32 %X, %Y
|
|
|
|
ret i32 %Z
|
2010-08-28 04:44:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @test33(i32 %X) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test33(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[TMP1_MASK:%.*]] = and i32 %X, 16777216
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1_MASK]], 0
|
|
|
|
; CHECK-NEXT: ret i1 [[TMP2]]
|
|
|
|
;
|
|
|
|
%tmp1 = shl i32 %X, 7
|
|
|
|
%tmp2 = icmp slt i32 %tmp1, 0
|
|
|
|
ret i1 %tmp2
|
2010-08-28 04:44:45 +08:00
|
|
|
}
|
|
|
|
|
2016-08-16 08:48:38 +08:00
|
|
|
define <2 x i1> @test33vec(<2 x i32> %X) {
|
|
|
|
; CHECK-LABEL: @test33vec(
|
2016-08-22 00:35:34 +08:00
|
|
|
; CHECK-NEXT: [[TMP1_MASK:%.*]] = and <2 x i32> %X, <i32 16777216, i32 16777216>
|
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i32> [[TMP1_MASK]], zeroinitializer
|
2016-08-16 08:48:38 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[TMP2]]
|
|
|
|
;
|
|
|
|
%tmp1 = shl <2 x i32> %X, <i32 7, i32 7>
|
|
|
|
%tmp2 = icmp slt <2 x i32> %tmp1, zeroinitializer
|
|
|
|
ret <2 x i1> %tmp2
|
|
|
|
}
|
|
|
|
|
2010-08-28 04:44:45 +08:00
|
|
|
define i1 @test34(i32 %X) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test34(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i1 false
|
|
|
|
;
|
|
|
|
%tmp1 = lshr i32 %X, 7
|
|
|
|
%tmp2 = icmp slt i32 %tmp1, 0
|
|
|
|
ret i1 %tmp2
|
2010-08-28 04:44:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
define i1 @test35(i32 %X) {
|
2013-07-14 09:42:54 +08:00
|
|
|
; CHECK-LABEL: @test35(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 %X, 0
|
|
|
|
; CHECK-NEXT: ret i1 [[TMP2]]
|
|
|
|
;
|
|
|
|
%tmp1 = ashr i32 %X, 7
|
|
|
|
%tmp2 = icmp slt i32 %tmp1, 0
|
|
|
|
ret i1 %tmp2
|
2010-08-28 04:44:45 +08:00
|
|
|
}
|
|
|
|
|
2016-09-12 23:51:42 +08:00
|
|
|
define <2 x i1> @test35vec(<2 x i32> %X) {
|
|
|
|
; CHECK-LABEL: @test35vec(
|
2016-09-13 00:25:41 +08:00
|
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i32> %X, zeroinitializer
|
2016-09-12 23:51:42 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i1> [[TMP2]]
|
|
|
|
;
|
|
|
|
%tmp1 = ashr <2 x i32> %X, <i32 7, i32 7>
|
|
|
|
%tmp2 = icmp slt <2 x i32> %tmp1, zeroinitializer
|
|
|
|
ret <2 x i1> %tmp2
|
|
|
|
}
|
|
|
|
|
2010-08-28 06:24:38 +08:00
|
|
|
define i128 @test36(i128 %A, i128 %B) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test36(
|
|
|
|
; CHECK-NEXT: [[TMP231:%.*]] = or i128 %B, %A
|
|
|
|
; CHECK-NEXT: [[INS:%.*]] = and i128 [[TMP231]], 18446744073709551615
|
|
|
|
; CHECK-NEXT: ret i128 [[INS]]
|
|
|
|
;
|
2010-08-28 06:24:38 +08:00
|
|
|
%tmp27 = shl i128 %A, 64
|
|
|
|
%tmp23 = shl i128 %B, 64
|
|
|
|
%ins = or i128 %tmp23, %tmp27
|
|
|
|
%tmp45 = lshr i128 %ins, 64
|
|
|
|
ret i128 %tmp45
|
|
|
|
}
|
|
|
|
|
2010-08-28 06:53:44 +08:00
|
|
|
define i64 @test37(i128 %A, i32 %B) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test37(
|
|
|
|
; CHECK-NEXT: [[TMP22:%.*]] = zext i32 %B to i128
|
|
|
|
; CHECK-NEXT: [[TMP23:%.*]] = shl nuw nsw i128 [[TMP22]], 32
|
|
|
|
; CHECK-NEXT: [[INS:%.*]] = or i128 [[TMP23]], %A
|
|
|
|
; CHECK-NEXT: [[TMP46:%.*]] = trunc i128 [[INS]] to i64
|
|
|
|
; CHECK-NEXT: ret i64 [[TMP46]]
|
|
|
|
;
|
2010-08-28 06:53:44 +08:00
|
|
|
%tmp27 = shl i128 %A, 64
|
|
|
|
%tmp22 = zext i32 %B to i128
|
|
|
|
%tmp23 = shl i128 %tmp22, 96
|
|
|
|
%ins = or i128 %tmp23, %tmp27
|
|
|
|
%tmp45 = lshr i128 %ins, 64
|
|
|
|
%tmp46 = trunc i128 %tmp45 to i64
|
|
|
|
ret i64 %tmp46
|
2017-01-14 02:27:23 +08:00
|
|
|
}
|
2014-04-14 15:03:13 +08:00
|
|
|
|
2017-01-14 02:27:23 +08:00
|
|
|
define <2 x i32> @shl_nuw_nsw_splat_vec(<2 x i8> %x) {
|
|
|
|
; CHECK-LABEL: @shl_nuw_nsw_splat_vec(
|
|
|
|
; CHECK-NEXT: [[T2:%.*]] = zext <2 x i8> %x to <2 x i32>
|
2017-01-14 02:39:09 +08:00
|
|
|
; CHECK-NEXT: [[T3:%.*]] = shl nuw nsw <2 x i32> [[T2]], <i32 17, i32 17>
|
2017-01-14 02:27:23 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[T3]]
|
|
|
|
;
|
|
|
|
%t2 = zext <2 x i8> %x to <2 x i32>
|
|
|
|
%t3 = shl <2 x i32> %t2, <i32 17, i32 17>
|
|
|
|
ret <2 x i32> %t3
|
2010-08-28 06:53:44 +08:00
|
|
|
}
|
2010-11-24 02:52:42 +08:00
|
|
|
|
|
|
|
define i32 @test38(i32 %x) nounwind readnone {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test38(
|
|
|
|
; CHECK-NEXT: [[REM1:%.*]] = and i32 %x, 31
|
|
|
|
; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[REM1]]
|
|
|
|
; CHECK-NEXT: ret i32 [[SHL]]
|
|
|
|
;
|
2010-11-24 02:52:42 +08:00
|
|
|
%rem = srem i32 %x, 32
|
|
|
|
%shl = shl i32 1, %rem
|
|
|
|
ret i32 %shl
|
|
|
|
}
|
|
|
|
|
2010-12-24 07:56:24 +08:00
|
|
|
; <rdar://problem/8756731>
|
|
|
|
define i8 @test39(i32 %a0) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test39(
|
|
|
|
; CHECK-NEXT: entry:
|
|
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i32 %a0 to i8
|
|
|
|
; CHECK-NEXT: [[TMP5:%.*]] = shl i8 [[TMP4]], 5
|
|
|
|
; CHECK-NEXT: [[TMP49:%.*]] = shl i8 [[TMP4]], 6
|
|
|
|
; CHECK-NEXT: [[TMP50:%.*]] = and i8 [[TMP49]], 64
|
|
|
|
; CHECK-NEXT: [[TMP51:%.*]] = xor i8 [[TMP50]], [[TMP5]]
|
|
|
|
; CHECK-NEXT: [[TMP0:%.*]] = shl i8 [[TMP4]], 2
|
|
|
|
; CHECK-NEXT: [[TMP54:%.*]] = and i8 [[TMP0]], 16
|
|
|
|
; CHECK-NEXT: [[TMP551:%.*]] = or i8 [[TMP54]], [[TMP51]]
|
|
|
|
; CHECK-NEXT: ret i8 [[TMP551]]
|
|
|
|
;
|
2010-12-24 07:56:24 +08:00
|
|
|
entry:
|
|
|
|
%tmp4 = trunc i32 %a0 to i8
|
|
|
|
%tmp5 = shl i8 %tmp4, 5
|
|
|
|
%tmp48 = and i8 %tmp5, 32
|
|
|
|
%tmp49 = lshr i8 %tmp48, 5
|
|
|
|
%tmp50 = mul i8 %tmp49, 64
|
|
|
|
%tmp51 = xor i8 %tmp50, %tmp5
|
|
|
|
%tmp52 = and i8 %tmp51, -128
|
|
|
|
%tmp53 = lshr i8 %tmp52, 7
|
|
|
|
%tmp54 = mul i8 %tmp53, 16
|
|
|
|
%tmp55 = xor i8 %tmp54, %tmp51
|
|
|
|
ret i8 %tmp55
|
|
|
|
}
|
2011-04-29 16:15:41 +08:00
|
|
|
|
|
|
|
; PR9809
|
|
|
|
define i32 @test40(i32 %a, i32 %b) nounwind {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test40(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 %b, 2
|
|
|
|
; CHECK-NEXT: [[DIV:%.*]] = lshr i32 %a, [[TMP1]]
|
|
|
|
; CHECK-NEXT: ret i32 [[DIV]]
|
|
|
|
;
|
2011-04-29 16:15:41 +08:00
|
|
|
%shl1 = shl i32 1, %b
|
|
|
|
%shl2 = shl i32 %shl1, 2
|
|
|
|
%div = udiv i32 %a, %shl2
|
|
|
|
ret i32 %div
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test41(i32 %a, i32 %b) nounwind {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test41(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 8, %b
|
|
|
|
; CHECK-NEXT: ret i32 [[TMP1]]
|
|
|
|
;
|
2011-04-29 16:15:41 +08:00
|
|
|
%1 = shl i32 1, %b
|
|
|
|
%2 = shl i32 %1, 3
|
|
|
|
ret i32 %2
|
|
|
|
}
|
2011-05-23 08:21:50 +08:00
|
|
|
|
|
|
|
define i32 @test42(i32 %a, i32 %b) nounwind {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test42(
|
|
|
|
; CHECK-NEXT: [[DIV:%.*]] = lshr exact i32 4096, %b
|
|
|
|
; CHECK-NEXT: [[DIV2:%.*]] = udiv i32 %a, [[DIV]]
|
|
|
|
; CHECK-NEXT: ret i32 [[DIV2]]
|
|
|
|
;
|
2011-05-23 08:21:50 +08:00
|
|
|
%div = lshr i32 4096, %b ; must be exact otherwise we'd divide by zero
|
|
|
|
%div2 = udiv i32 %a, %div
|
|
|
|
ret i32 %div2
|
|
|
|
}
|
|
|
|
|
2016-05-21 06:08:16 +08:00
|
|
|
define <2 x i32> @test42vec(<2 x i32> %a, <2 x i32> %b) {
|
|
|
|
; CHECK-LABEL: @test42vec(
|
2016-05-22 23:41:53 +08:00
|
|
|
; CHECK-NEXT: [[DIV:%.*]] = lshr exact <2 x i32> <i32 4096, i32 4096>, %b
|
2016-05-21 06:08:16 +08:00
|
|
|
; CHECK-NEXT: [[DIV2:%.*]] = udiv <2 x i32> %a, [[DIV]]
|
|
|
|
; CHECK-NEXT: ret <2 x i32> [[DIV2]]
|
|
|
|
;
|
|
|
|
%div = lshr <2 x i32> <i32 4096, i32 4096>, %b ; must be exact otherwise we'd divide by zero
|
|
|
|
%div2 = udiv <2 x i32> %a, %div
|
|
|
|
ret <2 x i32> %div2
|
|
|
|
}
|
|
|
|
|
2011-05-23 08:21:50 +08:00
|
|
|
define i32 @test43(i32 %a, i32 %b) nounwind {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test43(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = add i32 %b, 12
|
|
|
|
; CHECK-NEXT: [[DIV2:%.*]] = lshr i32 %a, [[TMP1]]
|
|
|
|
; CHECK-NEXT: ret i32 [[DIV2]]
|
|
|
|
;
|
2011-05-23 08:21:50 +08:00
|
|
|
%div = shl i32 4096, %b ; must be exact otherwise we'd divide by zero
|
|
|
|
%div2 = udiv i32 %a, %div
|
|
|
|
ret i32 %div2
|
|
|
|
}
|
|
|
|
|
2011-07-29 08:18:19 +08:00
|
|
|
define i32 @test44(i32 %a) nounwind {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test44(
|
|
|
|
; CHECK-NEXT: [[Y:%.*]] = shl i32 %a, 5
|
|
|
|
; CHECK-NEXT: ret i32 [[Y]]
|
|
|
|
;
|
2011-07-29 08:18:19 +08:00
|
|
|
%y = shl nuw i32 %a, 1
|
|
|
|
%z = shl i32 %y, 4
|
|
|
|
ret i32 %z
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test45(i32 %a) nounwind {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test45(
|
|
|
|
; CHECK-NEXT: [[Y:%.*]] = lshr i32 %a, 5
|
|
|
|
; CHECK-NEXT: ret i32 [[Y]]
|
|
|
|
;
|
2011-07-29 08:18:19 +08:00
|
|
|
%y = lshr exact i32 %a, 1
|
|
|
|
%z = lshr i32 %y, 4
|
|
|
|
ret i32 %z
|
|
|
|
}
|
2012-01-01 05:30:22 +08:00
|
|
|
|
2017-01-31 02:17:14 +08:00
|
|
|
; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)
|
|
|
|
|
2012-01-01 05:30:22 +08:00
|
|
|
define i32 @test46(i32 %a) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test46(
|
|
|
|
; CHECK-NEXT: [[Z:%.*]] = ashr exact i32 %a, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[Z]]
|
|
|
|
;
|
2012-01-01 05:30:22 +08:00
|
|
|
%y = ashr exact i32 %a, 3
|
|
|
|
%z = shl i32 %y, 1
|
|
|
|
ret i32 %z
|
|
|
|
}
|
|
|
|
|
2017-01-31 02:17:14 +08:00
|
|
|
; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)
|
|
|
|
|
|
|
|
define <2 x i32> @test46_splat_vec(<2 x i32> %a) {
|
|
|
|
; CHECK-LABEL: @test46_splat_vec(
|
2017-01-31 02:40:23 +08:00
|
|
|
; CHECK-NEXT: [[Z:%.*]] = ashr exact <2 x i32> %a, <i32 2, i32 2>
|
2017-01-31 02:17:14 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[Z]]
|
|
|
|
;
|
|
|
|
%y = ashr exact <2 x i32> %a, <i32 3, i32 3>
|
|
|
|
%z = shl <2 x i32> %y, <i32 1, i32 1>
|
|
|
|
ret <2 x i32> %z
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)
|
|
|
|
|
|
|
|
define i8 @test47(i8 %a) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test47(
|
2017-01-31 02:17:14 +08:00
|
|
|
; CHECK-NEXT: [[Z:%.*]] = lshr exact i8 %a, 2
|
|
|
|
; CHECK-NEXT: ret i8 [[Z]]
|
2016-05-02 23:32:10 +08:00
|
|
|
;
|
2017-01-31 02:17:14 +08:00
|
|
|
%y = lshr exact i8 %a, 3
|
|
|
|
%z = shl i8 %y, 1
|
|
|
|
ret i8 %z
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X >>?exact C1) << C2 --> X >>?exact (C1-C2)
|
|
|
|
|
|
|
|
define <2 x i8> @test47_splat_vec(<2 x i8> %a) {
|
|
|
|
; CHECK-LABEL: @test47_splat_vec(
|
2017-01-31 02:40:23 +08:00
|
|
|
; CHECK-NEXT: [[Z:%.*]] = lshr exact <2 x i8> %a, <i8 2, i8 2>
|
2017-01-31 02:17:14 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i8> [[Z]]
|
|
|
|
;
|
|
|
|
%y = lshr exact <2 x i8> %a, <i8 3, i8 3>
|
|
|
|
%z = shl <2 x i8> %y, <i8 1, i8 1>
|
|
|
|
ret <2 x i8> %z
|
2012-01-01 05:30:22 +08:00
|
|
|
}
|
2012-01-04 17:28:29 +08:00
|
|
|
|
2017-01-30 00:52:59 +08:00
|
|
|
; (X >>u,exact C1) << C2 --> X << (C2-C1) when C2 > C1
|
|
|
|
|
2012-01-04 17:28:29 +08:00
|
|
|
define i32 @test48(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test48(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
2012-01-04 17:28:29 +08:00
|
|
|
%A = lshr exact i32 %x, 1
|
|
|
|
%B = shl i32 %A, 3
|
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
2017-01-30 00:52:59 +08:00
|
|
|
; Verify that wrap flags are preserved from the original 'shl'.
|
|
|
|
|
|
|
|
define i32 @test48_nuw_nsw(i32 %x) {
|
|
|
|
; CHECK-LABEL: @test48_nuw_nsw(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
|
|
|
%A = lshr exact i32 %x, 1
|
|
|
|
%B = shl nuw nsw i32 %A, 3
|
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X >>u,exact C1) << C2 --> X << (C2-C1) when splatted C2 > C1
|
|
|
|
|
|
|
|
define <2 x i32> @test48_splat_vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test48_splat_vec(
|
2017-01-30 01:11:18 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> %x, <i32 2, i32 2>
|
2017-01-30 00:52:59 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[B]]
|
|
|
|
;
|
|
|
|
%A = lshr exact <2 x i32> %x, <i32 1, i32 1>
|
|
|
|
%B = shl nsw nuw <2 x i32> %A, <i32 3, i32 3>
|
|
|
|
ret <2 x i32> %B
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X >>s,exact C1) << C2 --> X << (C2-C1) when C2 > C1
|
|
|
|
|
2012-01-04 17:28:29 +08:00
|
|
|
define i32 @test49(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test49(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
2012-01-04 17:28:29 +08:00
|
|
|
%A = ashr exact i32 %x, 1
|
|
|
|
%B = shl i32 %A, 3
|
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
2017-01-30 00:52:59 +08:00
|
|
|
; Verify that wrap flags are preserved from the original 'shl'.
|
|
|
|
|
|
|
|
define i32 @test49_nuw_nsw(i32 %x) {
|
|
|
|
; CHECK-LABEL: @test49_nuw_nsw(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nuw nsw i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
|
|
|
%A = ashr exact i32 %x, 1
|
|
|
|
%B = shl nuw nsw i32 %A, 3
|
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X >>s,exact C1) << C2 --> X << (C2-C1) when splatted C2 > C1
|
|
|
|
|
|
|
|
define <2 x i32> @test49_splat_vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test49_splat_vec(
|
2017-01-30 01:11:18 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nuw nsw <2 x i32> %x, <i32 2, i32 2>
|
2017-01-30 00:52:59 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[B]]
|
|
|
|
;
|
|
|
|
%A = ashr exact <2 x i32> %x, <i32 1, i32 1>
|
|
|
|
%B = shl nsw nuw <2 x i32> %A, <i32 3, i32 3>
|
|
|
|
ret <2 x i32> %B
|
|
|
|
}
|
|
|
|
|
2017-01-30 23:54:50 +08:00
|
|
|
; (X <<nsw C1) >>s C2 --> X >>s (C2-C1)
|
|
|
|
|
2012-01-04 17:28:29 +08:00
|
|
|
define i32 @test50(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test50(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = ashr i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
2012-01-04 17:28:29 +08:00
|
|
|
%A = shl nsw i32 %x, 1
|
|
|
|
%B = ashr i32 %A, 3
|
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
2017-01-30 23:54:50 +08:00
|
|
|
; (X <<nsw C1) >>s C2 --> X >>s (C2-C1)
|
2017-01-31 01:19:32 +08:00
|
|
|
; Also, check that exact is propagated.
|
2017-01-30 23:54:50 +08:00
|
|
|
|
|
|
|
define <2 x i32> @test50_splat_vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test50_splat_vec(
|
2017-01-31 01:19:32 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i32> %x, <i32 2, i32 2>
|
2017-01-30 23:54:50 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[B]]
|
|
|
|
;
|
|
|
|
%A = shl nsw <2 x i32> %x, <i32 1, i32 1>
|
2017-01-31 01:19:32 +08:00
|
|
|
%B = ashr exact <2 x i32> %A, <i32 3, i32 3>
|
2017-01-30 23:54:50 +08:00
|
|
|
ret <2 x i32> %B
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X <<nuw C1) >>u C2 --> X >>u (C2-C1)
|
|
|
|
|
2012-01-04 17:28:29 +08:00
|
|
|
define i32 @test51(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test51(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = lshr i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
2012-01-04 17:28:29 +08:00
|
|
|
%A = shl nuw i32 %x, 1
|
|
|
|
%B = lshr i32 %A, 3
|
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
2017-01-30 23:54:50 +08:00
|
|
|
; (X <<nuw C1) >>u C2 --> X >>u (C2-C1) with splats
|
|
|
|
; Also, check that exact is propagated.
|
|
|
|
|
|
|
|
define <2 x i32> @test51_splat_vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test51_splat_vec(
|
2017-01-31 00:11:40 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = lshr exact <2 x i32> %x, <i32 2, i32 2>
|
2017-01-30 23:54:50 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[B]]
|
|
|
|
;
|
|
|
|
%A = shl nuw <2 x i32> %x, <i32 1, i32 1>
|
|
|
|
%B = lshr exact <2 x i32> %A, <i32 3, i32 3>
|
|
|
|
ret <2 x i32> %B
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2)
|
2017-01-31 00:38:49 +08:00
|
|
|
; Also, check that exact is propagated.
|
2017-01-30 23:54:50 +08:00
|
|
|
|
|
|
|
define i32 @test51_no_nuw(i32 %x) {
|
|
|
|
; CHECK-LABEL: @test51_no_nuw(
|
2017-01-31 00:53:03 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr exact i32 %x, 2
|
2017-01-30 23:54:50 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = and i32 [[TMP1]], 536870911
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
|
|
|
%A = shl i32 %x, 1
|
2017-01-31 00:38:49 +08:00
|
|
|
%B = lshr exact i32 %A, 3
|
2017-01-30 23:54:50 +08:00
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
|
|
|
; (X << C1) >>u C2 --> X >>u (C2-C1) & (-1 >> C2)
|
|
|
|
|
|
|
|
define <2 x i32> @test51_no_nuw_splat_vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test51_no_nuw_splat_vec(
|
2017-01-31 00:11:40 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = lshr <2 x i32> %x, <i32 2, i32 2>
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[TMP1]], <i32 536870911, i32 536870911>
|
2017-01-30 23:54:50 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[B]]
|
|
|
|
;
|
|
|
|
%A = shl <2 x i32> %x, <i32 1, i32 1>
|
|
|
|
%B = lshr <2 x i32> %A, <i32 3, i32 3>
|
|
|
|
ret <2 x i32> %B
|
|
|
|
}
|
|
|
|
|
2017-01-31 07:26:17 +08:00
|
|
|
; (X <<nsw C1) >>s C2 --> X <<nsw (C1 - C2)
|
|
|
|
|
2012-01-04 17:28:29 +08:00
|
|
|
define i32 @test52(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test52(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nsw i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
2012-01-04 17:28:29 +08:00
|
|
|
%A = shl nsw i32 %x, 3
|
|
|
|
%B = ashr i32 %A, 1
|
|
|
|
ret i32 %B
|
|
|
|
}
|
|
|
|
|
2017-01-31 07:26:17 +08:00
|
|
|
; (X <<nsw C1) >>s C2 --> X <<nsw (C1 - C2)
|
|
|
|
|
|
|
|
define <2 x i32> @test52_splat_vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test52_splat_vec(
|
2017-01-31 07:35:52 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nsw <2 x i32> %x, <i32 2, i32 2>
|
2017-01-31 07:26:17 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[B]]
|
|
|
|
;
|
|
|
|
%A = shl nsw <2 x i32> %x, <i32 3, i32 3>
|
|
|
|
%B = ashr <2 x i32> %A, <i32 1, i32 1>
|
|
|
|
ret <2 x i32> %B
|
|
|
|
}
|
|
|
|
|
2017-01-31 07:01:05 +08:00
|
|
|
; (X <<nuw C1) >>u C2 --> X <<nuw (C1 - C2)
|
|
|
|
|
2012-01-04 17:28:29 +08:00
|
|
|
define i32 @test53(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test53(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nuw i32 %x, 2
|
|
|
|
; CHECK-NEXT: ret i32 [[B]]
|
|
|
|
;
|
2012-01-04 17:28:29 +08:00
|
|
|
%A = shl nuw i32 %x, 3
|
|
|
|
%B = lshr i32 %A, 1
|
|
|
|
ret i32 %B
|
|
|
|
}
|
2012-12-04 08:04:54 +08:00
|
|
|
|
2017-01-31 07:01:05 +08:00
|
|
|
; (X <<nuw C1) >>u C2 --> X <<nuw (C1 - C2)
|
|
|
|
|
2017-01-31 06:24:36 +08:00
|
|
|
define <2 x i32> @test53_splat_vec(<2 x i32> %x) {
|
|
|
|
; CHECK-LABEL: @test53_splat_vec(
|
2017-01-31 07:01:05 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = shl nuw <2 x i32> %x, <i32 2, i32 2>
|
2017-01-31 06:24:36 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i32> [[B]]
|
|
|
|
;
|
|
|
|
%A = shl nuw <2 x i32> %x, <i32 3, i32 3>
|
|
|
|
%B = lshr <2 x i32> %A, <i32 1, i32 1>
|
|
|
|
ret <2 x i32> %B
|
|
|
|
}
|
|
|
|
|
2017-01-31 07:01:05 +08:00
|
|
|
; (X << C1) >>u C2 --> X << (C1 - C2) & (-1 >> C2)
|
|
|
|
|
2017-01-31 06:24:36 +08:00
|
|
|
define i8 @test53_no_nuw(i8 %x) {
|
|
|
|
; CHECK-LABEL: @test53_no_nuw(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl i8 %x, 2
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = and i8 [[TMP1]], 124
|
|
|
|
; CHECK-NEXT: ret i8 [[B]]
|
|
|
|
;
|
|
|
|
%A = shl i8 %x, 3
|
|
|
|
%B = lshr i8 %A, 1
|
|
|
|
ret i8 %B
|
|
|
|
}
|
|
|
|
|
2017-01-31 07:01:05 +08:00
|
|
|
; (X << C1) >>u C2 --> X << (C1 - C2) & (-1 >> C2)
|
|
|
|
; FIXME: Demanded bits should change the mask constant as it does for the scalar case.
|
|
|
|
|
2017-01-31 06:24:36 +08:00
|
|
|
define <2 x i8> @test53_no_nuw_splat_vec(<2 x i8> %x) {
|
|
|
|
; CHECK-LABEL: @test53_no_nuw_splat_vec(
|
2017-01-31 07:01:05 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl <2 x i8> %x, <i8 2, i8 2>
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = and <2 x i8> [[TMP1]], <i8 127, i8 127>
|
2017-01-31 06:24:36 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i8> [[B]]
|
|
|
|
;
|
|
|
|
%A = shl <2 x i8> %x, <i8 3, i8 3>
|
|
|
|
%B = lshr <2 x i8> %A, <i8 1, i8 1>
|
|
|
|
ret <2 x i8> %B
|
|
|
|
}
|
|
|
|
|
2012-12-04 08:04:54 +08:00
|
|
|
define i32 @test54(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test54(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3
|
|
|
|
; CHECK-NEXT: [[AND:%.*]] = and i32 [[TMP1]], 16
|
|
|
|
; CHECK-NEXT: ret i32 [[AND]]
|
|
|
|
;
|
2012-12-04 08:04:54 +08:00
|
|
|
%shr2 = lshr i32 %x, 1
|
|
|
|
%shl = shl i32 %shr2, 4
|
|
|
|
%and = and i32 %shl, 16
|
|
|
|
ret i32 %and
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
define i32 @test55(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test55(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %x, 3
|
|
|
|
; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], 8
|
|
|
|
; CHECK-NEXT: ret i32 [[OR]]
|
|
|
|
;
|
2012-12-04 08:04:54 +08:00
|
|
|
%shr2 = lshr i32 %x, 1
|
|
|
|
%shl = shl i32 %shr2, 4
|
|
|
|
%or = or i32 %shl, 8
|
|
|
|
ret i32 %or
|
|
|
|
}
|
|
|
|
|
|
|
|
define i32 @test56(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test56(
|
|
|
|
; CHECK-NEXT: [[SHR2:%.*]] = lshr i32 %x, 1
|
|
|
|
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[SHR2]], 4
|
|
|
|
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], 7
|
|
|
|
; CHECK-NEXT: ret i32 [[OR]]
|
|
|
|
;
|
2012-12-04 08:04:54 +08:00
|
|
|
%shr2 = lshr i32 %x, 1
|
|
|
|
%shl = shl i32 %shr2, 4
|
|
|
|
%or = or i32 %shl, 7
|
|
|
|
ret i32 %or
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
define i32 @test57(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test57(
|
|
|
|
; CHECK-NEXT: [[SHR1:%.*]] = lshr i32 %x, 1
|
|
|
|
; CHECK-NEXT: [[SHL:%.*]] = shl i32 [[SHR1]], 4
|
|
|
|
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], 7
|
|
|
|
; CHECK-NEXT: ret i32 [[OR]]
|
|
|
|
;
|
2012-12-04 08:04:54 +08:00
|
|
|
%shr = ashr i32 %x, 1
|
|
|
|
%shl = shl i32 %shr, 4
|
|
|
|
%or = or i32 %shl, 7
|
|
|
|
ret i32 %or
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-12-09 18:35:19 +08:00
|
|
|
define i32 @test58(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test58(
|
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = ashr i32 %x, 3
|
|
|
|
; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], 1
|
|
|
|
; CHECK-NEXT: ret i32 [[OR]]
|
|
|
|
;
|
2012-12-04 08:04:54 +08:00
|
|
|
%shr = ashr i32 %x, 4
|
|
|
|
%shl = shl i32 %shr, 1
|
|
|
|
%or = or i32 %shl, 1
|
|
|
|
ret i32 %or
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-12-09 18:35:19 +08:00
|
|
|
define i32 @test59(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test59(
|
|
|
|
; CHECK-NEXT: [[SHR:%.*]] = ashr i32 %x, 4
|
|
|
|
; CHECK-NEXT: [[SHL:%.*]] = shl nsw i32 [[SHR]], 1
|
|
|
|
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], 2
|
|
|
|
; CHECK-NEXT: ret i32 [[OR]]
|
|
|
|
;
|
2012-12-04 08:04:54 +08:00
|
|
|
%shr = ashr i32 %x, 4
|
|
|
|
%shl = shl i32 %shr, 1
|
|
|
|
%or = or i32 %shl, 2
|
|
|
|
ret i32 %or
|
|
|
|
}
|
2012-12-12 08:29:03 +08:00
|
|
|
|
|
|
|
; propagate "exact" trait
|
2014-12-09 18:35:19 +08:00
|
|
|
define i32 @test60(i32 %x) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test60(
|
|
|
|
; CHECK-NEXT: [[SHL:%.*]] = ashr exact i32 %x, 3
|
|
|
|
; CHECK-NEXT: [[OR:%.*]] = or i32 [[SHL]], 1
|
|
|
|
; CHECK-NEXT: ret i32 [[OR]]
|
|
|
|
;
|
2012-12-12 08:29:03 +08:00
|
|
|
%shr = ashr exact i32 %x, 4
|
|
|
|
%shl = shl i32 %shr, 1
|
|
|
|
%or = or i32 %shl, 1
|
|
|
|
ret i32 %or
|
|
|
|
}
|
2013-08-30 22:35:35 +08:00
|
|
|
|
|
|
|
; PR17026
|
2014-12-09 18:35:19 +08:00
|
|
|
define void @test61(i128 %arg) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test61(
|
|
|
|
; CHECK-NEXT: bb:
|
|
|
|
; CHECK-NEXT: br i1 undef, label %bb1, label %bb12
|
|
|
|
; CHECK: bb1:
|
|
|
|
; CHECK-NEXT: br label %bb2
|
|
|
|
; CHECK: bb2:
|
|
|
|
; CHECK-NEXT: br i1 undef, label %bb3, label %bb7
|
|
|
|
; CHECK: bb3:
|
|
|
|
; CHECK-NEXT: br label %bb8
|
|
|
|
; CHECK: bb7:
|
|
|
|
; CHECK-NEXT: br i1 undef, label %bb8, label %bb2
|
|
|
|
; CHECK: bb8:
|
|
|
|
; CHECK-NEXT: br i1 undef, label %bb11, label %bb12
|
|
|
|
; CHECK: bb11:
|
|
|
|
; CHECK-NEXT: br i1 undef, label %bb1, label %bb12
|
|
|
|
; CHECK: bb12:
|
|
|
|
; CHECK-NEXT: ret void
|
|
|
|
;
|
2013-08-30 22:35:35 +08:00
|
|
|
bb:
|
|
|
|
br i1 undef, label %bb1, label %bb12
|
|
|
|
|
|
|
|
bb1: ; preds = %bb11, %bb
|
|
|
|
br label %bb2
|
|
|
|
|
|
|
|
bb2: ; preds = %bb7, %bb1
|
|
|
|
br i1 undef, label %bb3, label %bb7
|
|
|
|
|
|
|
|
bb3: ; preds = %bb2
|
|
|
|
%tmp = lshr i128 %arg, 36893488147419103232
|
|
|
|
%tmp4 = shl i128 %tmp, 0
|
|
|
|
%tmp5 = or i128 %tmp4, undef
|
|
|
|
%tmp6 = trunc i128 %tmp5 to i16
|
|
|
|
br label %bb8
|
|
|
|
|
|
|
|
bb7: ; preds = %bb2
|
|
|
|
br i1 undef, label %bb8, label %bb2
|
|
|
|
|
|
|
|
bb8: ; preds = %bb7, %bb3
|
|
|
|
%tmp9 = phi i16 [ %tmp6, %bb3 ], [ undef, %bb7 ]
|
|
|
|
%tmp10 = icmp eq i16 %tmp9, 0
|
|
|
|
br i1 %tmp10, label %bb11, label %bb12
|
|
|
|
|
|
|
|
bb11: ; preds = %bb8
|
|
|
|
br i1 undef, label %bb1, label %bb12
|
|
|
|
|
|
|
|
bb12: ; preds = %bb11, %bb8, %bb
|
|
|
|
ret void
|
|
|
|
}
|
2014-04-15 05:50:37 +08:00
|
|
|
|
2014-12-09 18:35:19 +08:00
|
|
|
define i32 @test62(i32 %a) {
|
|
|
|
; CHECK-LABEL: @test62(
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret i32 undef
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%b = ashr i32 %a, 32 ; shift all bits out
|
|
|
|
ret i32 %b
|
|
|
|
}
|
|
|
|
|
2014-12-09 18:35:19 +08:00
|
|
|
define <4 x i32> @test62_splat_vector(<4 x i32> %a) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test62_splat_vector(
|
|
|
|
; CHECK-NEXT: ret <4 x i32> undef
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%b = ashr <4 x i32> %a, <i32 32, i32 32, i32 32, i32 32> ; shift all bits out
|
|
|
|
ret <4 x i32> %b
|
|
|
|
}
|
|
|
|
|
2014-12-09 18:35:19 +08:00
|
|
|
define <4 x i32> @test62_non_splat_vector(<4 x i32> %a) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test62_non_splat_vector(
|
|
|
|
; CHECK-NEXT: [[B:%.*]] = ashr <4 x i32> %a, <i32 32, i32 0, i32 1, i32 2>
|
|
|
|
; CHECK-NEXT: ret <4 x i32> [[B]]
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%b = ashr <4 x i32> %a, <i32 32, i32 0, i32 1, i32 2> ; shift all bits out
|
|
|
|
ret <4 x i32> %b
|
|
|
|
}
|
|
|
|
|
2014-12-09 18:35:19 +08:00
|
|
|
define <2 x i65> @test_63(<2 x i64> %t) {
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-LABEL: @test_63(
|
|
|
|
; CHECK-NEXT: [[A:%.*]] = zext <2 x i64> %t to <2 x i65>
|
|
|
|
; CHECK-NEXT: [[SEXT:%.*]] = shl <2 x i65> [[A]], <i65 33, i65 33>
|
2017-01-16 00:38:19 +08:00
|
|
|
; CHECK-NEXT: [[B:%.*]] = ashr exact <2 x i65> [[SEXT]], <i65 33, i65 33>
|
2016-05-02 23:32:10 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i65> [[B]]
|
|
|
|
;
|
2014-04-15 05:50:37 +08:00
|
|
|
%a = zext <2 x i64> %t to <2 x i65>
|
|
|
|
%sext = shl <2 x i65> %a, <i65 33, i65 33>
|
|
|
|
%b = ashr <2 x i65> %sext, <i65 33, i65 33>
|
|
|
|
ret <2 x i65> %b
|
|
|
|
}
|
2017-01-04 10:21:34 +08:00
|
|
|
|
|
|
|
define i64 @test_64(i32 %t) {
|
|
|
|
; CHECK-LABEL: @test_64(
|
2017-01-30 00:52:59 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl i32 %t, 8
|
|
|
|
; CHECK-NEXT: [[SHL:%.*]] = zext i32 [[TMP1]] to i64
|
|
|
|
; CHECK-NEXT: ret i64 [[SHL]]
|
|
|
|
;
|
2017-01-04 10:21:34 +08:00
|
|
|
%and = and i32 %t, 16777215
|
|
|
|
%ext = zext i32 %and to i64
|
|
|
|
%shl = shl i64 %ext, 8
|
|
|
|
ret i64 %shl
|
|
|
|
}
|
2017-01-14 02:27:23 +08:00
|
|
|
|
|
|
|
define <2 x i64> @test_64_splat_vec(<2 x i32> %t) {
|
|
|
|
; CHECK-LABEL: @test_64_splat_vec(
|
|
|
|
; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> %t, <i32 16777215, i32 16777215>
|
2017-01-14 02:39:09 +08:00
|
|
|
; CHECK-NEXT: [[TMP1:%.*]] = shl nuw <2 x i32> [[AND]], <i32 8, i32 8>
|
|
|
|
; CHECK-NEXT: [[SHL:%.*]] = zext <2 x i32> [[TMP1]] to <2 x i64>
|
2017-01-14 02:27:23 +08:00
|
|
|
; CHECK-NEXT: ret <2 x i64> [[SHL]]
|
|
|
|
;
|
|
|
|
%and = and <2 x i32> %t, <i32 16777215, i32 16777215>
|
|
|
|
%ext = zext <2 x i32> %and to <2 x i64>
|
|
|
|
%shl = shl <2 x i64> %ext, <i64 8, i64 8>
|
|
|
|
ret <2 x i64> %shl
|
|
|
|
}
|
|
|
|
|