[llvm] 41aab93 - [InstCombine] bitcast(logic(bitcast(X), bitcast(Y))) -> bitcast'(logic(bitcast'(X), Y))
Chenbing Zheng via llvm-commits
llvm-commits at lists.llvm.org
Wed May 25 20:04:53 PDT 2022
Author: Chenbing Zheng
Date: 2022-05-26T10:23:44+08:00
New Revision: 41aab93afc23e8f338c3617161e42d7ff54da74b
URL: https://github.com/llvm/llvm-project/commit/41aab93afc23e8f338c3617161e42d7ff54da74b
DIFF: https://github.com/llvm/llvm-project/commit/41aab93afc23e8f338c3617161e42d7ff54da74b.diff
LOG: [InstCombine] bitcast(logic(bitcast(X), bitcast(Y))) -> bitcast'(logic(bitcast'(X), Y))
This patch break foldBitCastBitwiseLogic limite the destination
must have an integer element type, and eliminate one bitcast by
doing the logic op in the type of the input that has an integer
element type.
Reviewed By: spatel
Differential Revision: https://reviews.llvm.org/D126184
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
llvm/test/Transforms/InstCombine/bitcast-inseltpoison.ll
llvm/test/Transforms/InstCombine/bitcast.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index d000d79d5e383..9fb266bd60c75 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -2377,8 +2377,8 @@ static Instruction *foldBitCastBitwiseLogic(BitCastInst &BitCast,
InstCombiner::BuilderTy &Builder) {
Type *DestTy = BitCast.getType();
BinaryOperator *BO;
- if (!DestTy->isIntOrIntVectorTy() ||
- !match(BitCast.getOperand(0), m_OneUse(m_BinOp(BO))) ||
+
+ if (!match(BitCast.getOperand(0), m_OneUse(m_BinOp(BO))) ||
!BO->isBitwiseLogicOp())
return nullptr;
@@ -2388,6 +2388,32 @@ static Instruction *foldBitCastBitwiseLogic(BitCastInst &BitCast,
if (!DestTy->isVectorTy() || !BO->getType()->isVectorTy())
return nullptr;
+ if (DestTy->isFPOrFPVectorTy()) {
+ Value *X, *Y;
+ // bitcast(logic(bitcast(X), bitcast(Y))) -> bitcast'(logic(bitcast'(X), Y))
+ if (match(BO->getOperand(0), m_OneUse(m_BitCast(m_Value(X)))) &&
+ match(BO->getOperand(1), m_OneUse(m_BitCast(m_Value(Y))))) {
+ if (X->getType()->isFPOrFPVectorTy() &&
+ Y->getType()->isIntOrIntVectorTy()) {
+ Value *CastedOp =
+ Builder.CreateBitCast(BO->getOperand(0), Y->getType());
+ Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, Y);
+ return CastInst::CreateBitOrPointerCast(NewBO, DestTy);
+ }
+ if (X->getType()->isIntOrIntVectorTy() &&
+ Y->getType()->isFPOrFPVectorTy()) {
+ Value *CastedOp =
+ Builder.CreateBitCast(BO->getOperand(1), X->getType());
+ Value *NewBO = Builder.CreateBinOp(BO->getOpcode(), CastedOp, X);
+ return CastInst::CreateBitOrPointerCast(NewBO, DestTy);
+ }
+ }
+ return nullptr;
+ }
+
+ if (!DestTy->isIntOrIntVectorTy())
+ return nullptr;
+
Value *X;
if (match(BO->getOperand(0), m_OneUse(m_BitCast(m_Value(X)))) &&
X->getType() == DestTy && !isa<Constant>(X)) {
diff --git a/llvm/test/Transforms/InstCombine/bitcast-inseltpoison.ll b/llvm/test/Transforms/InstCombine/bitcast-inseltpoison.ll
index 4e244a76b07dc..95edb21f7340b 100644
--- a/llvm/test/Transforms/InstCombine/bitcast-inseltpoison.ll
+++ b/llvm/test/Transforms/InstCombine/bitcast-inseltpoison.ll
@@ -130,16 +130,11 @@ define <4 x i32> @bitcasts_and_bitcast(<4 x i32> %a, <8 x i16> %b) {
ret <4 x i32> %bc3
}
-; The destination must have an integer element type.
-; FIXME: We can still eliminate one bitcast in this test by doing the logic op
-; in the type of the input that has an integer element type.
-
define <4 x float> @bitcasts_and_bitcast_to_fp(<4 x float> %a, <8 x i16> %b) {
; CHECK-LABEL: @bitcasts_and_bitcast_to_fp(
-; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x float> [[A:%.*]] to <2 x i64>
-; CHECK-NEXT: [[BC2:%.*]] = bitcast <8 x i16> [[B:%.*]] to <2 x i64>
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[BC2]], [[BC1]]
-; CHECK-NEXT: [[BC3:%.*]] = bitcast <2 x i64> [[AND]] to <4 x float>
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x i16>
+; CHECK-NEXT: [[TMP2:%.*]] = and <8 x i16> [[TMP1]], [[B:%.*]]
+; CHECK-NEXT: [[BC3:%.*]] = bitcast <8 x i16> [[TMP2]] to <4 x float>
; CHECK-NEXT: ret <4 x float> [[BC3]]
;
%bc1 = bitcast <4 x float> %a to <2 x i64>
diff --git a/llvm/test/Transforms/InstCombine/bitcast.ll b/llvm/test/Transforms/InstCombine/bitcast.ll
index da2ff8e3d9445..eb30719c75f2c 100644
--- a/llvm/test/Transforms/InstCombine/bitcast.ll
+++ b/llvm/test/Transforms/InstCombine/bitcast.ll
@@ -4,6 +4,8 @@
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0.0"
+declare void @use_vec(<2 x i64>)
+
; Bitcasts between vectors and scalars are valid.
; PR4487
define i32 @test1(i64 %a) {
@@ -130,16 +132,11 @@ define <4 x i32> @bitcasts_and_bitcast(<4 x i32> %a, <8 x i16> %b) {
ret <4 x i32> %bc3
}
-; The destination must have an integer element type.
-; FIXME: We can still eliminate one bitcast in this test by doing the logic op
-; in the type of the input that has an integer element type.
-
define <4 x float> @bitcasts_and_bitcast_to_fp(<4 x float> %a, <8 x i16> %b) {
; CHECK-LABEL: @bitcasts_and_bitcast_to_fp(
-; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x float> [[A:%.*]] to <2 x i64>
-; CHECK-NEXT: [[BC2:%.*]] = bitcast <8 x i16> [[B:%.*]] to <2 x i64>
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[BC2]], [[BC1]]
-; CHECK-NEXT: [[BC3:%.*]] = bitcast <2 x i64> [[AND]] to <4 x float>
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x i16>
+; CHECK-NEXT: [[TMP2:%.*]] = and <8 x i16> [[TMP1]], [[B:%.*]]
+; CHECK-NEXT: [[BC3:%.*]] = bitcast <8 x i16> [[TMP2]] to <4 x float>
; CHECK-NEXT: ret <4 x float> [[BC3]]
;
%bc1 = bitcast <4 x float> %a to <2 x i64>
@@ -149,17 +146,49 @@ define <4 x float> @bitcasts_and_bitcast_to_fp(<4 x float> %a, <8 x i16> %b) {
ret <4 x float> %bc3
}
-define <4 x float> @bitcasts_or_bitcast_to_fp(<4 x float> %a, <8 x i16> %b) {
+define <2 x double> @bitcasts_or_bitcast_to_fp(<4 x float> %a, <8 x i16> %b) {
; CHECK-LABEL: @bitcasts_or_bitcast_to_fp(
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[A:%.*]] to <8 x i16>
+; CHECK-NEXT: [[TMP2:%.*]] = or <8 x i16> [[TMP1]], [[B:%.*]]
+; CHECK-NEXT: [[BC3:%.*]] = bitcast <8 x i16> [[TMP2]] to <2 x double>
+; CHECK-NEXT: ret <2 x double> [[BC3]]
+;
+ %bc1 = bitcast <4 x float> %a to <2 x i64>
+ %bc2 = bitcast <8 x i16> %b to <2 x i64>
+ %and = or <2 x i64> %bc1, %bc2
+ %bc3 = bitcast <2 x i64> %and to <2 x double>
+ ret <2 x double> %bc3
+}
+
+define <4 x float> @bitcasts_xor_bitcast_to_fp(<2 x double> %a, <8 x i16> %b) {
+; CHECK-LABEL: @bitcasts_xor_bitcast_to_fp(
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[A:%.*]] to <8 x i16>
+; CHECK-NEXT: [[TMP2:%.*]] = xor <8 x i16> [[TMP1]], [[B:%.*]]
+; CHECK-NEXT: [[BC3:%.*]] = bitcast <8 x i16> [[TMP2]] to <4 x float>
+; CHECK-NEXT: ret <4 x float> [[BC3]]
+;
+ %bc1 = bitcast <8 x i16> %b to <2 x i64>
+ %bc2 = bitcast <2 x double> %a to <2 x i64>
+ %xor = xor <2 x i64> %bc2, %bc1
+ %bc3 = bitcast <2 x i64> %xor to <4 x float>
+ ret <4 x float> %bc3
+}
+
+; Negative test
+
+define <4 x float> @bitcasts_and_bitcast_to_fp_multiuse(<4 x float> %a, <8 x i16> %b) {
+; CHECK-LABEL: @bitcasts_and_bitcast_to_fp_multiuse(
; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x float> [[A:%.*]] to <2 x i64>
; CHECK-NEXT: [[BC2:%.*]] = bitcast <8 x i16> [[B:%.*]] to <2 x i64>
-; CHECK-NEXT: [[AND:%.*]] = or <2 x i64> [[BC1]], [[BC2]]
+; CHECK-NEXT: call void @use_vec(<2 x i64> [[BC2]])
+; CHECK-NEXT: [[AND:%.*]] = and <2 x i64> [[BC2]], [[BC1]]
; CHECK-NEXT: [[BC3:%.*]] = bitcast <2 x i64> [[AND]] to <4 x float>
; CHECK-NEXT: ret <4 x float> [[BC3]]
;
%bc1 = bitcast <4 x float> %a to <2 x i64>
%bc2 = bitcast <8 x i16> %b to <2 x i64>
- %and = or <2 x i64> %bc1, %bc2
+ call void @use_vec(<2 x i64> %bc2)
+ %and = and <2 x i64> %bc2, %bc1
%bc3 = bitcast <2 x i64> %and to <4 x float>
ret <4 x float> %bc3
}
More information about the llvm-commits
mailing list