-
Notifications
You must be signed in to change notification settings - Fork 10.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[X86][GlobalISel] Enable G_SDIV/G_UDIV/G_SREM/G_UREM #81615
Conversation
e-kud
commented
Feb 13, 2024
•
edited
edited
- Create a libcall for s64 type for 32 bit targets.
- Fix a bug in REM selection: SUBREG_TO_REG is not intended to produce a value from super registers.
- Replace selector tests by end-to-end tests. Other passes check the selected MIR better.
* Create a libcall for s64 type for 32 bit targets. * Fix a bug in REM selection: SUBREG_TO_REG is not intended to produce a value from super registers. * Replace per-pass tests by end-to-end tests. They haven't revealed the aforementioned bug.
@llvm/pr-subscribers-backend-x86 @llvm/pr-subscribers-llvm-globalisel Author: Evgenii Kudriashov (e-kud) Changes
Patch is 130.70 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81615.diff 22 Files Affected:
diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index 26932ba2c8e242..8e0f61a855661b 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -1778,12 +1778,9 @@ bool X86InstructionSelector::selectMulDivRem(MachineInstr &I,
.addImm(8);
// Now reference the 8-bit subreg of the result.
- BuildMI(*I.getParent(), I, I.getDebugLoc(),
- TII.get(TargetOpcode::SUBREG_TO_REG))
- .addDef(DstReg)
- .addImm(0)
- .addReg(ResultSuperReg)
- .addImm(X86::sub_8bit);
+ BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
+ DstReg)
+ .addReg(ResultSuperReg, 0, X86::sub_8bit);
} else {
BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY),
DstReg)
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 27381dff338e2d..4e83753b67e7e5 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -212,6 +212,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
return typeInSet(0, {s8, s16, s32})(Query) ||
(Is64Bit && typeInSet(0, {s64})(Query));
})
+ .libcallFor({s64})
.clampScalar(0, s8, sMaxScalar);
// integer shifts
diff --git a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir b/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir
deleted file mode 100644
index 80382db942722c..00000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-sdiv.mir
+++ /dev/null
@@ -1,114 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=i686-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
-
---- |
- ; ModuleID = 'sdiv.ll'
- source_filename = "sdiv.ll"
- target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
- define i8 @test_sdiv_i8(i8 %arg1, i8 %arg2) {
- %res = sdiv i8 %arg1, %arg2
- ret i8 %res
- }
-
- define i16 @test_sdiv_i16(i16 %arg1, i16 %arg2) {
- %res = sdiv i16 %arg1, %arg2
- ret i16 %res
- }
-
- define i32 @test_sdiv_i32(i32 %arg1, i32 %arg2) {
- %res = sdiv i32 %arg1, %arg2
- ret i32 %res
- }
-
-...
----
-name: test_sdiv_i8
-alignment: 16
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _ }
- - { id: 1, class: _ }
- - { id: 2, class: _ }
- - { id: 3, class: _ }
- - { id: 4, class: _ }
-body: |
- bb.1 (%ir-block.0):
- liveins: $edi, $esi
-
- ; CHECK-LABEL: name: test_sdiv_i8
- ; CHECK: liveins: $edi, $esi
- ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
- ; CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[SDIV:%[0-9]+]]:_(s8) = G_SDIV [[TRUNC]], [[TRUNC1]]
- ; CHECK: $al = COPY [[SDIV]](s8)
- ; CHECK: RET 0, implicit $al
- %2:_(s32) = COPY $edi
- %0:_(s8) = G_TRUNC %2(s32)
- %3:_(s32) = COPY $esi
- %1:_(s8) = G_TRUNC %3(s32)
- %4:_(s8) = G_SDIV %0, %1
- $al = COPY %4(s8)
- RET 0, implicit $al
-
-...
----
-name: test_sdiv_i16
-alignment: 16
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _ }
- - { id: 1, class: _ }
- - { id: 2, class: _ }
- - { id: 3, class: _ }
- - { id: 4, class: _ }
-body: |
- bb.1 (%ir-block.0):
- liveins: $edi, $esi
-
- ; CHECK-LABEL: name: test_sdiv_i16
- ; CHECK: liveins: $edi, $esi
- ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
- ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[SDIV:%[0-9]+]]:_(s16) = G_SDIV [[TRUNC]], [[TRUNC1]]
- ; CHECK: $ax = COPY [[SDIV]](s16)
- ; CHECK: RET 0, implicit $ax
- %2:_(s32) = COPY $edi
- %0:_(s16) = G_TRUNC %2(s32)
- %3:_(s32) = COPY $esi
- %1:_(s16) = G_TRUNC %3(s32)
- %4:_(s16) = G_SDIV %0, %1
- $ax = COPY %4(s16)
- RET 0, implicit $ax
-
-...
----
-name: test_sdiv_i32
-alignment: 16
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _ }
- - { id: 1, class: _ }
- - { id: 2, class: _ }
-body: |
- bb.1 (%ir-block.0):
- liveins: $edi, $esi
-
- ; CHECK-LABEL: name: test_sdiv_i32
- ; CHECK: liveins: $edi, $esi
- ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
- ; CHECK: [[SDIV:%[0-9]+]]:_(s32) = G_SDIV [[COPY]], [[COPY1]]
- ; CHECK: $eax = COPY [[SDIV]](s32)
- ; CHECK: RET 0, implicit $eax
- %0:_(s32) = COPY $edi
- %1:_(s32) = COPY $esi
- %2:_(s32) = G_SDIV %0, %1
- $eax = COPY %2(s32)
- RET 0, implicit $eax
-
-...
diff --git a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-srem.mir b/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-srem.mir
deleted file mode 100644
index 965bf635d6feb8..00000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-srem.mir
+++ /dev/null
@@ -1,211 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=i686-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
-
---- |
- ; ModuleID = 'srem.ll'
- source_filename = "srem.ll"
- target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
- target triple = "i386--linux-gnu"
-
- define i8 @test_srem_i8(i8 %arg1, i8 %arg2) {
- %res = srem i8 %arg1, %arg2
- ret i8 %res
- }
-
- define i16 @test_srem_i16(i16 %arg1, i16 %arg2) {
- %res = srem i16 %arg1, %arg2
- ret i16 %res
- }
-
- define i32 @test_srem_i32(i32 %arg1, i32 %arg2) {
- %res = srem i32 %arg1, %arg2
- ret i32 %res
- }
-
-...
----
-name: test_srem_i8
-alignment: 16
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _, preferred-register: '' }
- - { id: 1, class: _, preferred-register: '' }
- - { id: 2, class: _, preferred-register: '' }
- - { id: 3, class: _, preferred-register: '' }
- - { id: 4, class: _, preferred-register: '' }
-liveins:
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 0
- offsetAdjustment: 0
- maxAlignment: 4
- adjustsStack: false
- hasCalls: false
- stackProtector: ''
- maxCallFrameSize: 4294967295
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack:
- - { id: 0, type: default, offset: 4, size: 1, alignment: 4, stack-id: default,
- isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- - { id: 1, type: default, offset: 0, size: 1, alignment: 16, stack-id: default,
- isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-stack:
-constants:
-body: |
- bb.1 (%ir-block.0):
- ; CHECK-LABEL: name: test_srem_i8
- ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; CHECK: [[LOAD:%[0-9]+]]:_(s8) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s8) from %fixed-stack.0, align 16)
- ; CHECK: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
- ; CHECK: [[LOAD1:%[0-9]+]]:_(s8) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (s8) from %fixed-stack.1, align 4)
- ; CHECK: [[SREM:%[0-9]+]]:_(s8) = G_SREM [[LOAD]], [[LOAD1]]
- ; CHECK: $al = COPY [[SREM]](s8)
- ; CHECK: RET 0, implicit $al
- %2:_(p0) = G_FRAME_INDEX %fixed-stack.1
- %0:_(s8) = G_LOAD %2(p0) :: (invariant load (s8) from %fixed-stack.1, align 16)
- %3:_(p0) = G_FRAME_INDEX %fixed-stack.0
- %1:_(s8) = G_LOAD %3(p0) :: (invariant load (s8) from %fixed-stack.0, align 4)
- %4:_(s8) = G_SREM %0, %1
- $al = COPY %4(s8)
- RET 0, implicit $al
-
-...
----
-name: test_srem_i16
-alignment: 16
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _, preferred-register: '' }
- - { id: 1, class: _, preferred-register: '' }
- - { id: 2, class: _, preferred-register: '' }
- - { id: 3, class: _, preferred-register: '' }
- - { id: 4, class: _, preferred-register: '' }
-liveins:
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 0
- offsetAdjustment: 0
- maxAlignment: 4
- adjustsStack: false
- hasCalls: false
- stackProtector: ''
- maxCallFrameSize: 4294967295
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack:
- - { id: 0, type: default, offset: 4, size: 2, alignment: 4, stack-id: default,
- isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- - { id: 1, type: default, offset: 0, size: 2, alignment: 16, stack-id: default,
- isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-stack:
-constants:
-body: |
- bb.1 (%ir-block.0):
- ; CHECK-LABEL: name: test_srem_i16
- ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; CHECK: [[LOAD:%[0-9]+]]:_(s16) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s16) from %fixed-stack.0, align 16)
- ; CHECK: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
- ; CHECK: [[LOAD1:%[0-9]+]]:_(s16) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (s16) from %fixed-stack.1, align 4)
- ; CHECK: [[SREM:%[0-9]+]]:_(s16) = G_SREM [[LOAD]], [[LOAD1]]
- ; CHECK: $ax = COPY [[SREM]](s16)
- ; CHECK: RET 0, implicit $ax
- %2:_(p0) = G_FRAME_INDEX %fixed-stack.1
- %0:_(s16) = G_LOAD %2(p0) :: (invariant load (s16) from %fixed-stack.1, align 16)
- %3:_(p0) = G_FRAME_INDEX %fixed-stack.0
- %1:_(s16) = G_LOAD %3(p0) :: (invariant load (s16) from %fixed-stack.0, align 4)
- %4:_(s16) = G_SREM %0, %1
- $ax = COPY %4(s16)
- RET 0, implicit $ax
-
-...
----
-name: test_srem_i32
-alignment: 16
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _, preferred-register: '' }
- - { id: 1, class: _, preferred-register: '' }
- - { id: 2, class: _, preferred-register: '' }
- - { id: 3, class: _, preferred-register: '' }
- - { id: 4, class: _, preferred-register: '' }
-liveins:
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 0
- offsetAdjustment: 0
- maxAlignment: 4
- adjustsStack: false
- hasCalls: false
- stackProtector: ''
- maxCallFrameSize: 4294967295
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack:
- - { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: default,
- isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
- - { id: 1, type: default, offset: 0, size: 4, alignment: 16, stack-id: default,
- isImmutable: true, isAliased: false, callee-saved-register: '', callee-saved-restored: true,
- debug-info-variable: '', debug-info-expression: '', debug-info-location: '' }
-stack:
-constants:
-body: |
- bb.1 (%ir-block.0):
- ; CHECK-LABEL: name: test_srem_i32
- ; CHECK: [[FRAME_INDEX:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.0
- ; CHECK: [[LOAD:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX]](p0) :: (invariant load (s32) from %fixed-stack.0, align 16)
- ; CHECK: [[FRAME_INDEX1:%[0-9]+]]:_(p0) = G_FRAME_INDEX %fixed-stack.1
- ; CHECK: [[LOAD1:%[0-9]+]]:_(s32) = G_LOAD [[FRAME_INDEX1]](p0) :: (invariant load (s32) from %fixed-stack.1)
- ; CHECK: [[SREM:%[0-9]+]]:_(s32) = G_SREM [[LOAD]], [[LOAD1]]
- ; CHECK: $eax = COPY [[SREM]](s32)
- ; CHECK: RET 0, implicit $eax
- %2:_(p0) = G_FRAME_INDEX %fixed-stack.1
- %0:_(s32) = G_LOAD %2(p0) :: (invariant load (s32) from %fixed-stack.1, align 16)
- %3:_(p0) = G_FRAME_INDEX %fixed-stack.0
- %1:_(s32) = G_LOAD %3(p0) :: (invariant load (s32) from %fixed-stack.0, align 4)
- %4:_(s32) = G_SREM %0, %1
- $eax = COPY %4(s32)
- RET 0, implicit $eax
-
-...
diff --git a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-udiv.mir b/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-udiv.mir
deleted file mode 100644
index 85c9b6d9e86bfd..00000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-udiv.mir
+++ /dev/null
@@ -1,195 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=i686-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
-
---- |
- ; ModuleID = 'udiv.ll'
- source_filename = "udiv.ll"
- target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
- define i8 @test_udiv_i8(i8 %arg1, i8 %arg2) {
- %res = udiv i8 %arg1, %arg2
- ret i8 %res
- }
-
- define i16 @test_udiv_i16(i16 %arg1, i16 %arg2) {
- %res = udiv i16 %arg1, %arg2
- ret i16 %res
- }
-
- define i32 @test_udiv_i32(i32 %arg1, i32 %arg2) {
- %res = udiv i32 %arg1, %arg2
- ret i32 %res
- }
-
-...
----
-name: test_udiv_i8
-alignment: 16
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _, preferred-register: '' }
- - { id: 1, class: _, preferred-register: '' }
- - { id: 2, class: _, preferred-register: '' }
- - { id: 3, class: _, preferred-register: '' }
- - { id: 4, class: _, preferred-register: '' }
-liveins:
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 0
- offsetAdjustment: 0
- maxAlignment: 0
- adjustsStack: false
- hasCalls: false
- stackProtector: ''
- maxCallFrameSize: 4294967295
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack:
-stack:
-constants:
-body: |
- bb.1 (%ir-block.0):
- liveins: $edi, $esi
-
- ; CHECK-LABEL: name: test_udiv_i8
- ; CHECK: liveins: $edi, $esi
- ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY]](s32)
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
- ; CHECK: [[TRUNC1:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[UDIV:%[0-9]+]]:_(s8) = G_UDIV [[TRUNC]], [[TRUNC1]]
- ; CHECK: $al = COPY [[UDIV]](s8)
- ; CHECK: RET 0, implicit $al
- %2:_(s32) = COPY $edi
- %0:_(s8) = G_TRUNC %2(s32)
- %3:_(s32) = COPY $esi
- %1:_(s8) = G_TRUNC %3(s32)
- %4:_(s8) = G_UDIV %0, %1
- $al = COPY %4(s8)
- RET 0, implicit $al
-
-...
----
-name: test_udiv_i16
-alignment: 16
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _, preferred-register: '' }
- - { id: 1, class: _, preferred-register: '' }
- - { id: 2, class: _, preferred-register: '' }
- - { id: 3, class: _, preferred-register: '' }
- - { id: 4, class: _, preferred-register: '' }
-liveins:
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 0
- offsetAdjustment: 0
- maxAlignment: 0
- adjustsStack: false
- hasCalls: false
- stackProtector: ''
- maxCallFrameSize: 4294967295
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack:
-stack:
-constants:
-body: |
- bb.1 (%ir-block.0):
- liveins: $edi, $esi
-
- ; CHECK-LABEL: name: test_udiv_i16
- ; CHECK: liveins: $edi, $esi
- ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
- ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY]](s32)
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
- ; CHECK: [[TRUNC1:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32)
- ; CHECK: [[UDIV:%[0-9]+]]:_(s16) = G_UDIV [[TRUNC]], [[TRUNC1]]
- ; CHECK: $ax = COPY [[UDIV]](s16)
- ; CHECK: RET 0, implicit $ax
- %2:_(s32) = COPY $edi
- %0:_(s16) = G_TRUNC %2(s32)
- %3:_(s32) = COPY $esi
- %1:_(s16) = G_TRUNC %3(s32)
- %4:_(s16) = G_UDIV %0, %1
- $ax = COPY %4(s16)
- RET 0, implicit $ax
-
-...
----
-name: test_udiv_i32
-alignment: 16
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _, preferred-register: '' }
- - { id: 1, class: _, preferred-register: '' }
- - { id: 2, class: _, preferred-register: '' }
-liveins:
-frameInfo:
- isFrameAddressTaken: false
- isReturnAddressTaken: false
- hasStackMap: false
- hasPatchPoint: false
- stackSize: 0
- offsetAdjustment: 0
- maxAlignment: 0
- adjustsStack: false
- hasCalls: false
- stackProtector: ''
- maxCallFrameSize: 4294967295
- hasOpaqueSPAdjustment: false
- hasVAStart: false
- hasMustTailInVarArgFunc: false
- localFrameSize: 0
- savePoint: ''
- restorePoint: ''
-fixedStack:
-stack:
-constants:
-body: |
- bb.1 (%ir-block.0):
- liveins: $edi, $esi
-
- ; CHECK-LABEL: name: test_udiv_i32
- ; CHECK: liveins: $edi, $esi
- ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY $edi
- ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY $esi
- ; CHECK: [[UDIV:%[0-9]+]]:_(s32) = G_UDIV [[COPY]], [[COPY1]]
- ; CHECK: $eax = COPY [[UDIV]](s32)
- ; CHECK: RET 0, implicit $eax
- %0:_(s32) = COPY $edi
- %1:_(s32) = COPY $esi
- %2:_(s32) = G_UDIV %0, %1
- $eax = COPY %2(s32)
- RET 0, implicit $eax
-
-...
diff --git a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-urem.mir b/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-urem.mir
deleted file mode 100644
index b6496216ac56da..00000000000000
--- a/llvm/test/CodeGen/X86/GlobalISel/x86-legalize-urem.mir
+++ /dev/null
@@ -1,211 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
-# RUN: llc -mtriple=i686-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s
-
---- |
- ; ModuleID = 'urem.ll'
- source_filename = "urem.ll"
- target datalayout = "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128"
- target triple = "i386--linux-gnu"
-
- define i8 @test_urem_i8(i8 %arg1, i8 %arg2) {
- %res = urem i8 %arg1, %arg2
- ret i8 %res
- }
-
- define i16 @test_urem_i16(i16 %arg1, i16 %arg2) {
- %res = urem i16 %arg1, %arg2
- ret i16 %res
- }
-
- define i32 @test_urem_i32(i32 %arg1, i32 %arg2) {
- %res = urem i32 %arg1, %arg2
- ret i32 %res
- }
-
-...
----
-name: test_urem_i8
-alignment: 16
-exposesReturnsTwice: false
-legalized: false
-regBankSelected: false
-selected: false
-failedISel: false
-tracksRegLiveness: true
-registers:
- - { id: 0, class: _, preferred-register: '' }
- - { id: 1, class: _, preferred-register: '' }
- - { id: 2, class: _, preferred-register: '' }
- - { id: 3, class: _, preferred-register: '' }
- - { id: 4, class: _, preferred-register: '' }
-liveins:
-fr...
[truncated]
|
One of the nice features of GlobalIsel is that you can test passes in isolation. Why did the mir tests did not reveal the bug? |
Neither is a replacement for each other. I would add new end to end tests, not delete existing MIR tests |
I would also amend the select mir files to show the fixed bug. |
They show the SUBREG_TO_REG, but SUBREG_TO_REG is often misunderstood and there's nothing that can check that is correctly used. |
@@ -1778,12 +1778,9 @@ bool X86InstructionSelector::selectMulDivRem(MachineInstr &I, | |||
.addImm(8); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably for another patch, but we should match SelectionDAG here and use a MOVZX_NOREX or MOVSX_NOREX from AH here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean to replace COPY
+ SHR
by movzx %ah, %ax
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is the code from X86ISelDAGToDAG.cpp
if (HiReg == X86::AH && !SDValue(Node, 1).use_empty()) {
SDValue AHCopy = CurDAG->getRegister(X86::AH, MVT::i8);
unsigned AHExtOpcode =
isSigned ? X86::MOVSX32rr8_NOREX : X86::MOVZX32rr8_NOREX;
SDNode *RNode = CurDAG->getMachineNode(AHExtOpcode, dl, MVT::i32,
MVT::Glue, AHCopy, InGlue);
SDValue Result(RNode, 0);
InGlue = SDValue(RNode, 1);
Result =
CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result);
ReplaceUses(SDValue(Node, 1), Result);
LLVM_DEBUG(dbgs() << "=> "; Result.getNode()->dump(CurDAG);
dbgs() << '\n');
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be losing the legalize tests (although maybe we should be merging 32/64 bit targets - no i64 divrem on x86 tests atm)? The select tests I don't find as much use for (and the isel-* tests are better to identify poor codegen IMO)
We really should just remove SUBREG_TO_REG, it's impossible to use it correctly. My patch to hack around it in the coalescer is currently stuck on it's 5th or 6th revert due to unrelated issues it happens to hit |
I want to admit that it was too harsh to replace all @tschuett do you think we still need updated select tests? These tests won't be much different from the existing ones that check invalid MIR. I think that the best check of instruction selection is valid final assembly. But I don't mind to keep them if we see their usefulness. Before fix it was an assert in register allocator due to |
@topperc maybe we can add a subreg-superreg check to |
Not really, the operation is more fundamentally broken. It is promising something about bits in registers which are not represented in the instruction |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm with nits
# RUN: llc -mtriple=i686-linux-gnu -run-pass=legalizer -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,X86 | ||
|
||
--- | | ||
source_filename = "sdiv.ll" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need the IR section
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've always thought that IR section is needed to regenerate MIR if something has changed. Or is it not a common practice?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's needed for a specific set of IR references (block names, IR values in MMOs, and global references)
; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=X86,DAG-X86 | ||
; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=X86,GISEL-X86 | ||
|
||
define i8 @test_sdiv_i8(i8 %arg1, i8 %arg2) nounwind { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe want vector tests somewhere too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FTR - I'd prefer vector tests to be in separate files as there is a lot of SSE/AVX level bloat
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@arsenm the vector work is in parallel with scalar instruction. We've started with some basics G_BUILD_VECTOR
and G_INSERT/EXTRACT_VECTOR_ELT
. We'll reiterate all operations ones more with adding tests for vector operands.
@RKSimon I agree with splitting vector/scalar cases, as well as float/scalar in some situations. I'm mostly motivated by creating a generic testsuite that can be reused for other targets when they start adding GlobalISel support incrementally. I'm slightly struggling with existing mixed vector/float/int tests that I need to split for GlobalISel testing as not everything's implemented or to duplicate them.
However maybe this is not feasible as after some time there will be tests for non-standard sizes like i42
that nobody will support at early stages.