[llvm] 6da7dbb - [GlobalISel]: Allow targets to override how to widen constants during legalization

Aditya Nandakumar via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 3 10:49:31 PST 2019


Author: Aditya Nandakumar
Date: 2019-12-03T10:41:10-08:00
New Revision: 6da7dbb806dce9fbc05416482a5b895efdea96b0

URL: https://github.com/llvm/llvm-project/commit/6da7dbb806dce9fbc05416482a5b895efdea96b0
DIFF: https://github.com/llvm/llvm-project/commit/6da7dbb806dce9fbc05416482a5b895efdea96b0.diff

LOG: [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.

Added: 
    

Modified: 
    llvm/include/llvm/CodeGen/GlobalISel/LegalizerInfo.h
    llvm/include/llvm/Support/LowLevelTypeImpl.h
    llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
    llvm/lib/CodeGen/GlobalISel/LegalizerInfo.cpp
    llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-consts.mir
    llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-fp.mir
    llvm/test/CodeGen/Mips/GlobalISel/legalizer/constants.mir
    llvm/test/CodeGen/Mips/GlobalISel/legalizer/select.mir
    llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/constants.ll
    llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/fcmp.ll
    llvm/test/CodeGen/Mips/GlobalISel/llvm-ir/select.ll
    llvm/test/CodeGen/X86/GlobalISel/ashr-scalar.ll
    llvm/test/CodeGen/X86/GlobalISel/legalize-constant.mir
    llvm/test/CodeGen/X86/GlobalISel/lshr-scalar.ll
    llvm/test/CodeGen/X86/GlobalISel/shl-scalar.ll

Removed: 
    


################################################################################
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 @@ class LegalizerInfo {
   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 @@ class LLT {
                       : 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


        


More information about the llvm-commits mailing list