diff --git a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h index d184530d6447..642f8828b0f5 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h @@ -1157,6 +1157,12 @@ public: virtual bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder) const; + /// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while + /// widening a constant of type SmallTy which targets can override. + /// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which + /// will be the default. + virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const; + private: /// Determine what action should be taken to legalize the given generic /// instruction opcode, type-index and type. Requires computeTables to have diff --git a/llvm/include/llvm/Support/LowLevelTypeImpl.h b/llvm/include/llvm/Support/LowLevelTypeImpl.h index 0e02b6e7d750..6ef7c298bc28 100644 --- a/llvm/include/llvm/Support/LowLevelTypeImpl.h +++ b/llvm/include/llvm/Support/LowLevelTypeImpl.h @@ -137,6 +137,8 @@ public: : LLT::scalar(NewEltSize); } + bool isByteSized() const { return (getSizeInBits() & 7) == 0; } + unsigned getScalarSizeInBits() const { assert(RawData != 0 && "Invalid Type"); if (!IsVector) { diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp index d8bcc59c7658..a9af31f882e6 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -1675,7 +1675,15 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) { case TargetOpcode::G_CONSTANT: { MachineOperand &SrcMO = MI.getOperand(1); LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext(); - const APInt &Val = SrcMO.getCImm()->getValue().sext(WideTy.getSizeInBits()); + unsigned ExtOpc = LI.getExtOpcodeForWideningConstant( + MRI.getType(MI.getOperand(0).getReg())); + assert((ExtOpc == TargetOpcode::G_ZEXT || ExtOpc == TargetOpcode::G_SEXT || + ExtOpc == TargetOpcode::G_ANYEXT) && + "Illegal Extend"); + const APInt &SrcVal = SrcMO.getCImm()->getValue(); + const APInt &Val = (ExtOpc == TargetOpcode::G_SEXT) + ? SrcVal.sext(WideTy.getSizeInBits()) + : SrcVal.zext(WideTy.getSizeInBits()); Observer.changingInstr(MI); SrcMO.setCImm(ConstantInt::get(Ctx, Val)); diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp index 70045512fae5..f897f9c7e20a 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp @@ -685,6 +685,10 @@ bool LegalizerInfo::legalizeIntrinsic(MachineInstr &MI, return true; } +unsigned LegalizerInfo::getExtOpcodeForWideningConstant(LLT SmallTy) const { + return SmallTy.isByteSized() ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT; +} + /// \pre Type indices of every opcode form a dense set starting from 0. void LegalizerInfo::verify(const MCInstrInfo &MII) const { #ifndef NDEBUG diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-consts.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-consts.mir index de5545594bf3..9d6620921105 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-consts.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-consts.mir @@ -44,7 +44,7 @@ body: | %3(s1) = G_CONSTANT i1 1 G_STORE %3(s1), %4(p0) :: (store 1) ; CHECK-NOT: G_CONSTANT i1 - ; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 + ; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; CHECK: {{%[0-9]+}}:_(s1) = G_TRUNC [[EXT]](s32) ; CHECK-NOT: G_CONSTANT i1 diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir index b413130558e6..0cdab2c41f79 100644 --- a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir +++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir @@ -1131,10 +1131,9 @@ body: | ; SOFT-NOT: G_FCMP ; For soft float we just need to return a '-1' constant, but the truncation ; to 1 bit is converted by the combiner to the following masking sequence. - ; SOFT: [[R:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 - ; SOFT: [[MASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; SOFT: [[R:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; SOFT: [[RCOPY:%[0-9]+]]:_(s32) = COPY [[R]](s32) - ; SOFT: [[REXT:%[0-9]+]]:_(s32) = G_AND [[RCOPY]], [[MASK]] + ; SOFT: [[REXT:%[0-9]+]]:_(s32) = G_AND [[RCOPY]], [[R]] ; SOFT-NOT: G_FCMP ; CHECK: $r0 = COPY [[REXT]] ... @@ -1853,11 +1852,10 @@ body: | ; HARD: [[R:%[0-9]+]]:_(s1) = G_FCMP floatpred(true), [[X]](s64), [[Y]] ; HARD: [[REXT:%[0-9]+]]:_(s32) = G_ZEXT [[R]](s1) ; SOFT-NOT: G_FCMP - ; SOFT: [[R:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 ; The result needs to be truncated, and the combiner turns the truncation ; into the following masking sequence. ; SOFT: [[MASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 - ; SOFT: [[RCOPY:%[0-9]+]]:_(s32) = COPY [[R]] + ; SOFT: [[RCOPY:%[0-9]+]]:_(s32) = COPY [[MASK]] ; SOFT: [[REXT:%[0-9]+]]:_(s32) = G_AND [[RCOPY]], [[MASK]] ; SOFT-NOT: G_FCMP %7(s32) = G_ZEXT %6(s1) diff --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/constants.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/constants.mir index 5a805af18ded..e30870b73635 100644 --- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/constants.mir +++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/constants.mir @@ -131,10 +131,9 @@ tracksRegLiveness: true body: | bb.1.entry: ; MIPS32-LABEL: name: i1_true - ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 - ; MIPS32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 + ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32) - ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C1]] + ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]] ; MIPS32: $v0 = COPY [[AND]](s32) ; MIPS32: RetRA implicit $v0 %0:_(s1) = G_CONSTANT i1 true diff --git a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir index 59d4280e1ba8..057abae4d819 100644 --- a/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir +++ b/llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir @@ -150,14 +150,13 @@ body: | ; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1 ; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2 ; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3 - ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 + ; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; MIPS32: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY]](s32), [[COPY1]] ; MIPS32: [[COPY4:%[0-9]+]]:_(s32) = COPY [[ICMP]](s32) ; MIPS32: [[COPY5:%[0-9]+]]:_(s32) = COPY [[C]](s32) ; MIPS32: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[COPY4]], [[COPY5]] - ; MIPS32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; MIPS32: [[COPY6:%[0-9]+]]:_(s32) = COPY [[XOR]](s32) - ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY6]], [[C1]] + ; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY6]], [[C]] ; MIPS32: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[AND]](s32), [[COPY2]], [[COPY3]] ; MIPS32: $v0 = COPY [[SELECT]](s32) ; MIPS32: RetRA implicit $v0 diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/constants.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/constants.ll index bdafe26491a3..0187b72780d7 100644 --- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/constants.ll +++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/constants.ll @@ -71,7 +71,7 @@ entry: define zeroext i1 @i1_true() { ; MIPS32-LABEL: i1_true: ; MIPS32: # %bb.0: # %entry -; MIPS32-NEXT: addiu $1, $zero, 65535 +; MIPS32-NEXT: ori $1, $zero, 1 ; MIPS32-NEXT: andi $2, $1, 1 ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fcmp.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fcmp.ll index 8f559633c956..58d5c8a160a6 100644 --- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fcmp.ll +++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fcmp.ll @@ -15,7 +15,7 @@ entry: define i1 @true_s(float %x, float %y) { ; MIPS32-LABEL: true_s: ; MIPS32: # %bb.0: # %entry -; MIPS32-NEXT: addiu $2, $zero, 65535 +; MIPS32-NEXT: ori $2, $zero, 1 ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop entry: @@ -233,7 +233,7 @@ entry: define i1 @true_d(double %x, double %y) { ; MIPS32-LABEL: true_d: ; MIPS32: # %bb.0: # %entry -; MIPS32-NEXT: addiu $2, $zero, 65535 +; MIPS32-NEXT: ori $2, $zero, 1 ; MIPS32-NEXT: jr $ra ; MIPS32-NEXT: nop entry: diff --git a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll index c127d1208919..71c3023ca153 100644 --- a/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll +++ b/llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll @@ -56,8 +56,9 @@ entry: define i32 @select_with_negation(i32 %a, i32 %b, i32 %x, i32 %y) { ; MIPS32-LABEL: select_with_negation: ; MIPS32: # %bb.0: # %entry -; MIPS32-NEXT: slt $1, $4, $5 -; MIPS32-NEXT: not $1, $1 +; MIPS32-NEXT: ori $1, $zero, 1 +; MIPS32-NEXT: slt $2, $4, $5 +; MIPS32-NEXT: xor $1, $2, $1 ; MIPS32-NEXT: andi $1, $1, 1 ; MIPS32-NEXT: movn $7, $6, $1 ; MIPS32-NEXT: move $2, $7 diff --git a/llvm/test/CodeGen/X86/GlobalISel/ashr-scalar.ll b/llvm/test/CodeGen/X86/GlobalISel/ashr-scalar.ll index c24845edbddb..849cf0d4ce4c 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/ashr-scalar.ll +++ b/llvm/test/CodeGen/X86/GlobalISel/ashr-scalar.ll @@ -165,7 +165,7 @@ define i1 @test_ashr_i1_imm1(i32 %arg1) { ; X64-LABEL: test_ashr_i1_imm1: ; X64: # %bb.0: ; X64-NEXT: movl %edi, %eax -; X64-NEXT: movb $-1, %cl +; X64-NEXT: movb $1, %cl ; X64-NEXT: shlb $7, %al ; X64-NEXT: sarb $7, %al ; X64-NEXT: andb $1, %cl diff --git a/llvm/test/CodeGen/X86/GlobalISel/legalize-constant.mir b/llvm/test/CodeGen/X86/GlobalISel/legalize-constant.mir index 3b4bec6978f7..b89116e3a6cf 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/legalize-constant.mir +++ b/llvm/test/CodeGen/X86/GlobalISel/legalize-constant.mir @@ -18,7 +18,7 @@ registers: body: | bb.1 (%ir-block.0): ; X32-LABEL: name: test_constant - ; X32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 + ; X32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; X32: $eax = COPY [[C]](s32) ; X32: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 8 ; X32: $al = COPY [[C1]](s8) @@ -32,7 +32,7 @@ body: | ; X32: $rax = COPY [[MV]](s64) ; X32: RET 0 ; X64-LABEL: name: test_constant - ; X64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1 + ; X64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1 ; X64: $eax = COPY [[C]](s32) ; X64: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 8 ; X64: $al = COPY [[C1]](s8) diff --git a/llvm/test/CodeGen/X86/GlobalISel/lshr-scalar.ll b/llvm/test/CodeGen/X86/GlobalISel/lshr-scalar.ll index e935c1ca04bb..5dd53751247f 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/lshr-scalar.ll +++ b/llvm/test/CodeGen/X86/GlobalISel/lshr-scalar.ll @@ -164,7 +164,7 @@ define i1 @test_lshr_i1_imm1(i32 %arg1) { ; X64-LABEL: test_lshr_i1_imm1: ; X64: # %bb.0: ; X64-NEXT: movl %edi, %eax -; X64-NEXT: movb $-1, %cl +; X64-NEXT: movb $1, %cl ; X64-NEXT: andb $1, %al ; X64-NEXT: andb $1, %cl ; X64-NEXT: shrb %cl, %al diff --git a/llvm/test/CodeGen/X86/GlobalISel/shl-scalar.ll b/llvm/test/CodeGen/X86/GlobalISel/shl-scalar.ll index 49aa99e01c6c..5ccc0eee5951 100644 --- a/llvm/test/CodeGen/X86/GlobalISel/shl-scalar.ll +++ b/llvm/test/CodeGen/X86/GlobalISel/shl-scalar.ll @@ -162,7 +162,7 @@ define i1 @test_shl_i1_imm1(i32 %arg1) { ; X64-LABEL: test_shl_i1_imm1: ; X64: # %bb.0: ; X64-NEXT: movl %edi, %eax -; X64-NEXT: movb $-1, %cl +; X64-NEXT: movb $1, %cl ; X64-NEXT: andb $1, %cl ; X64-NEXT: shlb %cl, %al ; X64-NEXT: # kill: def $al killed $al killed $eax