@@ -846,8 +846,23 @@ class InterchangeableBinOp final : public InterchangeableInstruction {
846846 constexpr static std::initializer_list<unsigned> SupportedOp = {
847847 Instruction::Add, Instruction::Sub, Instruction::Mul, Instruction::Shl,
848848 Instruction::AShr, Instruction::And, Instruction::Or, Instruction::Xor};
849- // from high to low bit: Xor Or And Sub Add Mul AShr Shl
850- MaskType Mask = 0b11111111;
849+ enum : MaskType {
850+ SHL_BIT = 0b1,
851+ AShr_BIT = 0b10,
852+ Mul_BIT = 0b100,
853+ Add_BIT = 0b1000,
854+ Sub_BIT = 0b10000,
855+ And_BIT = 0b100000,
856+ Or_BIT = 0b1000000,
857+ Xor_BIT = 0b10000000,
858+ };
859+ // The bit it sets represents whether MainOp can be converted to.
860+ MaskType Mask = Xor_BIT | Or_BIT | And_BIT | Sub_BIT | Add_BIT | Mul_BIT |
861+ AShr_BIT | SHL_BIT;
862+ // We cannot create an interchangeable instruction that does not exist in VL.
863+ // For example, VL [x + 0, y * 1] can be converted to [x << 0, y << 0], but
864+ // 'shl' does not exist in VL. In the end, we convert VL to [x * 1, y * 1].
865+ // SeenBefore is used to know what operations have been seen before.
851866 MaskType SeenBefore = 0;
852867
853868 /// Return a non-nullptr if either operand of I is a ConstantInt.
@@ -876,21 +891,21 @@ class InterchangeableBinOp final : public InterchangeableInstruction {
876891 static MaskType opcodeToMask(unsigned Opcode) {
877892 switch (Opcode) {
878893 case Instruction::Shl:
879- return 0b1 ;
894+ return SHL_BIT ;
880895 case Instruction::AShr:
881- return 0b10 ;
896+ return AShr_BIT ;
882897 case Instruction::Mul:
883- return 0b100 ;
898+ return Mul_BIT ;
884899 case Instruction::Add:
885- return 0b1000 ;
900+ return Add_BIT ;
886901 case Instruction::Sub:
887- return 0b10000 ;
902+ return Sub_BIT ;
888903 case Instruction::And:
889- return 0b100000 ;
904+ return And_BIT ;
890905 case Instruction::Or:
891- return 0b1000000 ;
906+ return Or_BIT ;
892907 case Instruction::Xor:
893- return 0b10000000 ;
908+ return Xor_BIT ;
894909 }
895910 llvm_unreachable("Unsupported opcode.");
896911 }
@@ -917,12 +932,12 @@ class InterchangeableBinOp final : public InterchangeableInstruction {
917932 case Instruction::Shl:
918933 if (CIValue.isZero())
919934 return true;
920- return tryAnd(0b101 );
935+ return tryAnd(Mul_BIT | SHL_BIT );
921936 case Instruction::Mul:
922937 if (CIValue.isOne())
923938 return true;
924939 if (CIValue.isPowerOf2())
925- return tryAnd(0b101 );
940+ return tryAnd(Mul_BIT | SHL_BIT );
926941 break;
927942 case Instruction::And:
928943 if (CIValue.isAllOnes())
@@ -938,21 +953,21 @@ class InterchangeableBinOp final : public InterchangeableInstruction {
938953 }
939954 unsigned getOpcode() const override {
940955 MaskType Candidate = Mask & SeenBefore;
941- if (Candidate & 0b1 )
956+ if (Candidate & SHL_BIT )
942957 return Instruction::Shl;
943- if (Candidate & 0b10 )
958+ if (Candidate & AShr_BIT )
944959 return Instruction::AShr;
945- if (Candidate & 0b100 )
960+ if (Candidate & Mul_BIT )
946961 return Instruction::Mul;
947- if (Candidate & 0b1000 )
962+ if (Candidate & Add_BIT )
948963 return Instruction::Add;
949- if (Candidate & 0b10000 )
964+ if (Candidate & Sub_BIT )
950965 return Instruction::Sub;
951- if (Candidate & 0b100000 )
966+ if (Candidate & And_BIT )
952967 return Instruction::And;
953- if (Candidate & 0b1000000 )
968+ if (Candidate & Or_BIT )
954969 return Instruction::Or;
955- if (Candidate & 0b10000000 )
970+ if (Candidate & Xor_BIT )
956971 return Instruction::Xor;
957972 llvm_unreachable("Cannot find interchangeable instruction.");
958973 }
0 commit comments