Skip to content

Commit 6da7dbb

Browse files
author
Aditya Nandakumar
committed
[GlobalISel]: Allow targets to override how to widen constants during legalization
https://reviews.llvm.org/D70922 This adds a hook to allow targets to define exactly what extension operation should be performed for widening constants. This handles cases like widening i1 true which would end up becoming -1 which affects code quality during combines. Additionally, in order to stay consistent with how DAG is promoting constants, we now signextend for byte sized types and zero extend otherwise (by default). Targets can of course override this if necessary.
1 parent 444ac34 commit 6da7dbb

File tree

15 files changed

+40
-23
lines changed

15 files changed

+40
-23
lines changed

llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1157,6 +1157,12 @@ class LegalizerInfo {
11571157
virtual bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI,
11581158
MachineIRBuilder &MIRBuilder) const;
11591159

1160+
/// Return the opcode (SEXT/ZEXT/ANYEXT) that should be performed while
1161+
/// widening a constant of type SmallTy which targets can override.
1162+
/// For eg, the DAG does (SmallTy.isByteSized() ? G_SEXT : G_ZEXT) which
1163+
/// will be the default.
1164+
virtual unsigned getExtOpcodeForWideningConstant(LLT SmallTy) const;
1165+
11601166
private:
11611167
/// Determine what action should be taken to legalize the given generic
11621168
/// instruction opcode, type-index and type. Requires computeTables to have

llvm/include/llvm/Support/LowLevelTypeImpl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ class LLT {
137137
: LLT::scalar(NewEltSize);
138138
}
139139

140+
bool isByteSized() const { return (getSizeInBits() & 7) == 0; }
141+
140142
unsigned getScalarSizeInBits() const {
141143
assert(RawData != 0 && "Invalid Type");
142144
if (!IsVector) {

llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1675,7 +1675,15 @@ LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
16751675
case TargetOpcode::G_CONSTANT: {
16761676
MachineOperand &SrcMO = MI.getOperand(1);
16771677
LLVMContext &Ctx = MIRBuilder.getMF().getFunction().getContext();
1678-
const APInt &Val = SrcMO.getCImm()->getValue().sext(WideTy.getSizeInBits());
1678+
unsigned ExtOpc = LI.getExtOpcodeForWideningConstant(
1679+
MRI.getType(MI.getOperand(0).getReg()));
1680+
assert((ExtOpc == TargetOpcode::G_ZEXT || ExtOpc == TargetOpcode::G_SEXT ||
1681+
ExtOpc == TargetOpcode::G_ANYEXT) &&
1682+
"Illegal Extend");
1683+
const APInt &SrcVal = SrcMO.getCImm()->getValue();
1684+
const APInt &Val = (ExtOpc == TargetOpcode::G_SEXT)
1685+
? SrcVal.sext(WideTy.getSizeInBits())
1686+
: SrcVal.zext(WideTy.getSizeInBits());
16791687
Observer.changingInstr(MI);
16801688
SrcMO.setCImm(ConstantInt::get(Ctx, Val));
16811689

llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,10 @@ bool LegalizerInfo::legalizeIntrinsic(MachineInstr &MI,
685685
return true;
686686
}
687687

688+
unsigned LegalizerInfo::getExtOpcodeForWideningConstant(LLT SmallTy) const {
689+
return SmallTy.isByteSized() ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
690+
}
691+
688692
/// \pre Type indices of every opcode form a dense set starting from 0.
689693
void LegalizerInfo::verify(const MCInstrInfo &MII) const {
690694
#ifndef NDEBUG

llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-consts.mir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ body: |
4444
%3(s1) = G_CONSTANT i1 1
4545
G_STORE %3(s1), %4(p0) :: (store 1)
4646
; CHECK-NOT: G_CONSTANT i1
47-
; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
47+
; CHECK: [[EXT:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
4848
; CHECK: {{%[0-9]+}}:_(s1) = G_TRUNC [[EXT]](s32)
4949
; CHECK-NOT: G_CONSTANT i1
5050

llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,10 +1131,9 @@ body: |
11311131
; SOFT-NOT: G_FCMP
11321132
; For soft float we just need to return a '-1' constant, but the truncation
11331133
; to 1 bit is converted by the combiner to the following masking sequence.
1134-
; SOFT: [[R:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
1135-
; SOFT: [[MASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1134+
; SOFT: [[R:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
11361135
; SOFT: [[RCOPY:%[0-9]+]]:_(s32) = COPY [[R]](s32)
1137-
; SOFT: [[REXT:%[0-9]+]]:_(s32) = G_AND [[RCOPY]], [[MASK]]
1136+
; SOFT: [[REXT:%[0-9]+]]:_(s32) = G_AND [[RCOPY]], [[R]]
11381137
; SOFT-NOT: G_FCMP
11391138
; CHECK: $r0 = COPY [[REXT]]
11401139
...
@@ -1853,11 +1852,10 @@ body: |
18531852
; HARD: [[R:%[0-9]+]]:_(s1) = G_FCMP floatpred(true), [[X]](s64), [[Y]]
18541853
; HARD: [[REXT:%[0-9]+]]:_(s32) = G_ZEXT [[R]](s1)
18551854
; SOFT-NOT: G_FCMP
1856-
; SOFT: [[R:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
18571855
; The result needs to be truncated, and the combiner turns the truncation
18581856
; into the following masking sequence.
18591857
; SOFT: [[MASK:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
1860-
; SOFT: [[RCOPY:%[0-9]+]]:_(s32) = COPY [[R]]
1858+
; SOFT: [[RCOPY:%[0-9]+]]:_(s32) = COPY [[MASK]]
18611859
; SOFT: [[REXT:%[0-9]+]]:_(s32) = G_AND [[RCOPY]], [[MASK]]
18621860
; SOFT-NOT: G_FCMP
18631861
%7(s32) = G_ZEXT %6(s1)

llvm/test/CodeGen/Mips/GlobalISel/legalizer/constants.mir

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,9 @@ tracksRegLiveness: true
131131
body: |
132132
bb.1.entry:
133133
; MIPS32-LABEL: name: i1_true
134-
; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
135-
; MIPS32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
134+
; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
136135
; MIPS32: [[COPY:%[0-9]+]]:_(s32) = COPY [[C]](s32)
137-
; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C1]]
136+
; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY]], [[C]]
138137
; MIPS32: $v0 = COPY [[AND]](s32)
139138
; MIPS32: RetRA implicit $v0
140139
%0:_(s1) = G_CONSTANT i1 true

llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,13 @@ body: |
150150
; MIPS32: [[COPY1:%[0-9]+]]:_(s32) = COPY $a1
151151
; MIPS32: [[COPY2:%[0-9]+]]:_(s32) = COPY $a2
152152
; MIPS32: [[COPY3:%[0-9]+]]:_(s32) = COPY $a3
153-
; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
153+
; MIPS32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
154154
; MIPS32: [[ICMP:%[0-9]+]]:_(s32) = G_ICMP intpred(slt), [[COPY]](s32), [[COPY1]]
155155
; MIPS32: [[COPY4:%[0-9]+]]:_(s32) = COPY [[ICMP]](s32)
156156
; MIPS32: [[COPY5:%[0-9]+]]:_(s32) = COPY [[C]](s32)
157157
; MIPS32: [[XOR:%[0-9]+]]:_(s32) = G_XOR [[COPY4]], [[COPY5]]
158-
; MIPS32: [[C1:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
159158
; MIPS32: [[COPY6:%[0-9]+]]:_(s32) = COPY [[XOR]](s32)
160-
; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY6]], [[C1]]
159+
; MIPS32: [[AND:%[0-9]+]]:_(s32) = G_AND [[COPY6]], [[C]]
161160
; MIPS32: [[SELECT:%[0-9]+]]:_(s32) = G_SELECT [[AND]](s32), [[COPY2]], [[COPY3]]
162161
; MIPS32: $v0 = COPY [[SELECT]](s32)
163162
; MIPS32: RetRA implicit $v0

llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/constants.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ entry:
7171
define zeroext i1 @i1_true() {
7272
; MIPS32-LABEL: i1_true:
7373
; MIPS32: # %bb.0: # %entry
74-
; MIPS32-NEXT: addiu $1, $zero, 65535
74+
; MIPS32-NEXT: ori $1, $zero, 1
7575
; MIPS32-NEXT: andi $2, $1, 1
7676
; MIPS32-NEXT: jr $ra
7777
; MIPS32-NEXT: nop

llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fcmp.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ entry:
1515
define i1 @true_s(float %x, float %y) {
1616
; MIPS32-LABEL: true_s:
1717
; MIPS32: # %bb.0: # %entry
18-
; MIPS32-NEXT: addiu $2, $zero, 65535
18+
; MIPS32-NEXT: ori $2, $zero, 1
1919
; MIPS32-NEXT: jr $ra
2020
; MIPS32-NEXT: nop
2121
entry:
@@ -233,7 +233,7 @@ entry:
233233
define i1 @true_d(double %x, double %y) {
234234
; MIPS32-LABEL: true_d:
235235
; MIPS32: # %bb.0: # %entry
236-
; MIPS32-NEXT: addiu $2, $zero, 65535
236+
; MIPS32-NEXT: ori $2, $zero, 1
237237
; MIPS32-NEXT: jr $ra
238238
; MIPS32-NEXT: nop
239239
entry:

llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ entry:
5656
define i32 @select_with_negation(i32 %a, i32 %b, i32 %x, i32 %y) {
5757
; MIPS32-LABEL: select_with_negation:
5858
; MIPS32: # %bb.0: # %entry
59-
; MIPS32-NEXT: slt $1, $4, $5
60-
; MIPS32-NEXT: not $1, $1
59+
; MIPS32-NEXT: ori $1, $zero, 1
60+
; MIPS32-NEXT: slt $2, $4, $5
61+
; MIPS32-NEXT: xor $1, $2, $1
6162
; MIPS32-NEXT: andi $1, $1, 1
6263
; MIPS32-NEXT: movn $7, $6, $1
6364
; MIPS32-NEXT: move $2, $7

llvm/test/CodeGen/X86/GlobalISel/ashr-scalar.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ define i1 @test_ashr_i1_imm1(i32 %arg1) {
165165
; X64-LABEL: test_ashr_i1_imm1:
166166
; X64: # %bb.0:
167167
; X64-NEXT: movl %edi, %eax
168-
; X64-NEXT: movb $-1, %cl
168+
; X64-NEXT: movb $1, %cl
169169
; X64-NEXT: shlb $7, %al
170170
; X64-NEXT: sarb $7, %al
171171
; X64-NEXT: andb $1, %cl

llvm/test/CodeGen/X86/GlobalISel/legalize-constant.mir

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ registers:
1818
body: |
1919
bb.1 (%ir-block.0):
2020
; X32-LABEL: name: test_constant
21-
; X32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
21+
; X32: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
2222
; X32: $eax = COPY [[C]](s32)
2323
; X32: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
2424
; X32: $al = COPY [[C1]](s8)
@@ -32,7 +32,7 @@ body: |
3232
; X32: $rax = COPY [[MV]](s64)
3333
; X32: RET 0
3434
; X64-LABEL: name: test_constant
35-
; X64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 -1
35+
; X64: [[C:%[0-9]+]]:_(s32) = G_CONSTANT i32 1
3636
; X64: $eax = COPY [[C]](s32)
3737
; X64: [[C1:%[0-9]+]]:_(s8) = G_CONSTANT i8 8
3838
; X64: $al = COPY [[C1]](s8)

llvm/test/CodeGen/X86/GlobalISel/lshr-scalar.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ define i1 @test_lshr_i1_imm1(i32 %arg1) {
164164
; X64-LABEL: test_lshr_i1_imm1:
165165
; X64: # %bb.0:
166166
; X64-NEXT: movl %edi, %eax
167-
; X64-NEXT: movb $-1, %cl
167+
; X64-NEXT: movb $1, %cl
168168
; X64-NEXT: andb $1, %al
169169
; X64-NEXT: andb $1, %cl
170170
; X64-NEXT: shrb %cl, %al

llvm/test/CodeGen/X86/GlobalISel/shl-scalar.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ define i1 @test_shl_i1_imm1(i32 %arg1) {
162162
; X64-LABEL: test_shl_i1_imm1:
163163
; X64: # %bb.0:
164164
; X64-NEXT: movl %edi, %eax
165-
; X64-NEXT: movb $-1, %cl
165+
; X64-NEXT: movb $1, %cl
166166
; X64-NEXT: andb $1, %cl
167167
; X64-NEXT: shlb %cl, %al
168168
; X64-NEXT: # kill: def $al killed $al killed $eax

0 commit comments

Comments
 (0)