@@ -46,44 +46,6 @@ static Value *getFCmpValue(unsigned Code, Value *LHS, Value *RHS,
46
46
return Builder.CreateFCmp (NewPred, LHS, RHS);
47
47
}
48
48
49
- // / Transform BITWISE_OP(BSWAP(A),BSWAP(B)) or
50
- // / BITWISE_OP(BSWAP(A), Constant) to BSWAP(BITWISE_OP(A, B))
51
- // / \param I Binary operator to transform.
52
- // / \return Pointer to node that must replace the original binary operator, or
53
- // / null pointer if no transformation was made.
54
- static Value *SimplifyBSwap (BinaryOperator &I,
55
- InstCombiner::BuilderTy &Builder) {
56
- assert (I.isBitwiseLogicOp () && " Unexpected opcode for bswap simplifying" );
57
-
58
- Value *OldLHS = I.getOperand (0 );
59
- Value *OldRHS = I.getOperand (1 );
60
-
61
- Value *NewLHS;
62
- if (!match (OldLHS, m_BSwap (m_Value (NewLHS))))
63
- return nullptr ;
64
-
65
- Value *NewRHS;
66
- const APInt *C;
67
-
68
- if (match (OldRHS, m_BSwap (m_Value (NewRHS)))) {
69
- // OP( BSWAP(x), BSWAP(y) ) -> BSWAP( OP(x, y) )
70
- if (!OldLHS->hasOneUse () && !OldRHS->hasOneUse ())
71
- return nullptr ;
72
- // NewRHS initialized by the matcher.
73
- } else if (match (OldRHS, m_APInt (C))) {
74
- // OP( BSWAP(x), CONSTANT ) -> BSWAP( OP(x, BSWAP(CONSTANT) ) )
75
- if (!OldLHS->hasOneUse ())
76
- return nullptr ;
77
- NewRHS = ConstantInt::get (I.getType (), C->byteSwap ());
78
- } else
79
- return nullptr ;
80
-
81
- Value *BinOp = Builder.CreateBinOp (I.getOpcode (), NewLHS, NewRHS);
82
- Function *F = Intrinsic::getDeclaration (I.getModule (), Intrinsic::bswap,
83
- I.getType ());
84
- return Builder.CreateCall (F, BinOp);
85
- }
86
-
87
49
// / Emit a computation of: (V >= Lo && V < Hi) if Inside is true, otherwise
88
50
// / (V < Lo || V >= Hi). This method expects that Lo < Hi. IsSigned indicates
89
51
// / whether to treat V, Lo, and Hi as signed or not.
@@ -2159,6 +2121,64 @@ Instruction *InstCombinerImpl::foldBinOpOfDisplacedShifts(BinaryOperator &I) {
2159
2121
return BinaryOperator::Create (ShiftOp, NewC, ShAmt);
2160
2122
}
2161
2123
2124
+ // Fold and/or/xor with two equal intrinsic IDs:
2125
+ // bitwise(fshl (A, B, ShAmt), fshl(C, D, ShAmt))
2126
+ // -> fshl(bitwise(A, C), bitwise(B, D), ShAmt)
2127
+ // bitwise(fshr (A, B, ShAmt), fshr(C, D, ShAmt))
2128
+ // -> fshr(bitwise(A, C), bitwise(B, D), ShAmt)
2129
+ // bitwise(bswap(A), bswap(B)) -> bswap(bitwise(A, B))
2130
+ // bitwise(bswap(A), C) -> bswap(bitwise(A, bswap(C)))
2131
+ // bitwise(bitreverse(A), bitreverse(B)) -> bitreverse(bitwise(A, B))
2132
+ // bitwise(bitreverse(A), C) -> bitreverse(bitwise(A, bitreverse(C)))
2133
+ static Instruction *
2134
+ foldBitwiseLogicWithIntrinsics (BinaryOperator &I,
2135
+ InstCombiner::BuilderTy &Builder) {
2136
+ assert (I.isBitwiseLogicOp () && " Should and/or/xor" );
2137
+ if (!I.getOperand (0 )->hasOneUse ())
2138
+ return nullptr ;
2139
+ IntrinsicInst *X = dyn_cast<IntrinsicInst>(I.getOperand (0 ));
2140
+ if (!X)
2141
+ return nullptr ;
2142
+
2143
+ IntrinsicInst *Y = dyn_cast<IntrinsicInst>(I.getOperand (1 ));
2144
+ if (Y && (!Y->hasOneUse () || X->getIntrinsicID () != Y->getIntrinsicID ()))
2145
+ return nullptr ;
2146
+
2147
+ Intrinsic::ID IID = X->getIntrinsicID ();
2148
+ const APInt *RHSC;
2149
+ // Try to match constant RHS.
2150
+ if (!Y && (!(IID == Intrinsic::bswap || IID == Intrinsic::bitreverse) ||
2151
+ !match (I.getOperand (1 ), m_APInt (RHSC))))
2152
+ return nullptr ;
2153
+
2154
+ switch (IID) {
2155
+ case Intrinsic::fshl:
2156
+ case Intrinsic::fshr: {
2157
+ if (X->getOperand (2 ) != Y->getOperand (2 ))
2158
+ return nullptr ;
2159
+ Value *NewOp0 =
2160
+ Builder.CreateBinOp (I.getOpcode (), X->getOperand (0 ), Y->getOperand (0 ));
2161
+ Value *NewOp1 =
2162
+ Builder.CreateBinOp (I.getOpcode (), X->getOperand (1 ), Y->getOperand (1 ));
2163
+ Function *F = Intrinsic::getDeclaration (I.getModule (), IID, I.getType ());
2164
+ return CallInst::Create (F, {NewOp0, NewOp1, X->getOperand (2 )});
2165
+ }
2166
+ case Intrinsic::bswap:
2167
+ case Intrinsic::bitreverse: {
2168
+ Value *NewOp0 = Builder.CreateBinOp (
2169
+ I.getOpcode (), X->getOperand (0 ),
2170
+ Y ? Y->getOperand (0 )
2171
+ : ConstantInt::get (I.getType (), IID == Intrinsic::bswap
2172
+ ? RHSC->byteSwap ()
2173
+ : RHSC->reverseBits ()));
2174
+ Function *F = Intrinsic::getDeclaration (I.getModule (), IID, I.getType ());
2175
+ return CallInst::Create (F, {NewOp0});
2176
+ }
2177
+ default :
2178
+ return nullptr ;
2179
+ }
2180
+ }
2181
+
2162
2182
// FIXME: We use commutative matchers (m_c_*) for some, but not all, matches
2163
2183
// here. We should standardize that construct where it is needed or choose some
2164
2184
// other way to ensure that commutated variants of patterns are not missed.
@@ -2194,9 +2214,6 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
2194
2214
if (Value *V = foldUsingDistributiveLaws (I))
2195
2215
return replaceInstUsesWith (I, V);
2196
2216
2197
- if (Value *V = SimplifyBSwap (I, Builder))
2198
- return replaceInstUsesWith (I, V);
2199
-
2200
2217
if (Instruction *R = foldBinOpShiftWithShift (I))
2201
2218
return R;
2202
2219
@@ -2688,6 +2705,9 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
2688
2705
if (Instruction *Res = foldBinOpOfDisplacedShifts (I))
2689
2706
return Res;
2690
2707
2708
+ if (Instruction *Res = foldBitwiseLogicWithIntrinsics (I, Builder))
2709
+ return Res;
2710
+
2691
2711
return nullptr ;
2692
2712
}
2693
2713
@@ -3347,9 +3367,6 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
3347
3367
if (Value *V = foldUsingDistributiveLaws (I))
3348
3368
return replaceInstUsesWith (I, V);
3349
3369
3350
- if (Value *V = SimplifyBSwap (I, Builder))
3351
- return replaceInstUsesWith (I, V);
3352
-
3353
3370
Value *Op0 = I.getOperand (0 ), *Op1 = I.getOperand (1 );
3354
3371
Type *Ty = I.getType ();
3355
3372
if (Ty->isIntOrIntVectorTy (1 )) {
@@ -3884,6 +3901,9 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
3884
3901
return BinaryOperator::CreateAnd (X, ConstantInt::get (Ty, *C1 | *C2));
3885
3902
}
3886
3903
3904
+ if (Instruction *Res = foldBitwiseLogicWithIntrinsics (I, Builder))
3905
+ return Res;
3906
+
3887
3907
return nullptr ;
3888
3908
}
3889
3909
@@ -4507,9 +4527,6 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
4507
4527
if (SimplifyDemandedInstructionBits (I))
4508
4528
return &I;
4509
4529
4510
- if (Value *V = SimplifyBSwap (I, Builder))
4511
- return replaceInstUsesWith (I, V);
4512
-
4513
4530
if (Instruction *R = foldNot (I))
4514
4531
return R;
4515
4532
@@ -4799,5 +4816,8 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
4799
4816
if (Instruction *Res = foldBinOpOfDisplacedShifts (I))
4800
4817
return Res;
4801
4818
4819
+ if (Instruction *Res = foldBitwiseLogicWithIntrinsics (I, Builder))
4820
+ return Res;
4821
+
4802
4822
return nullptr ;
4803
4823
}
0 commit comments