Skip to content

Commit

Permalink
[AArch64][GlobalISel] Add legalizer & selector support for G_FREEZE.
Browse files Browse the repository at this point in the history
These should legalize like undefs and select into copies.

The ll test is copied from the x86 test, minus the half fp case because
we don't currently support that.
  • Loading branch information
aemerson committed May 18, 2020
1 parent b593bfd commit 665da59
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 3 deletions.
2 changes: 2 additions & 0 deletions llvm/lib/Target/AArch64/AArch64InstructionSelector.cpp
Expand Up @@ -2596,6 +2596,8 @@ bool AArch64InstructionSelector::select(MachineInstr &I) {
return true;
}

case TargetOpcode::G_FREEZE:
return selectCopy(I, TII, MRI, TRI, RBI);

case TargetOpcode::G_INTTOPTR:
// The importer is currently unable to import pointer types since they
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AArch64/AArch64LegalizerInfo.cpp
Expand Up @@ -58,7 +58,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST) {
return;
}

getActionDefinitionsBuilder(G_IMPLICIT_DEF)
getActionDefinitionsBuilder({G_IMPLICIT_DEF, G_FREEZE})
.legalFor({p0, s1, s8, s16, s32, s64, v2s32, v4s32, v2s64})
.clampScalar(0, s1, s64)
.widenScalarToNextPow2(0, 8)
Expand Down
149 changes: 149 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/freeze.ll
@@ -0,0 +1,149 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s 2>&1 | FileCheck %s
; RUN: llc -mtriple=aarch64-unknown-linux-gnu -global-isel -global-isel-abort=1 < %s 2>&1 | FileCheck %s --check-prefix=GISEL

%struct.T = type { i32, i32 }

define i32 @freeze_int() {
; CHECK-LABEL: freeze_int:
; CHECK: // %bb.0:
; CHECK-NEXT: mul w0, w8, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_int:
; GISEL: // %bb.0:
; GISEL-NEXT: mul w0, w8, w8
; GISEL-NEXT: ret
%y1 = freeze i32 undef
%t1 = mul i32 %y1, %y1
ret i32 %t1
}

define i5 @freeze_int2() {
; CHECK-LABEL: freeze_int2:
; CHECK: // %bb.0:
; CHECK-NEXT: mul w0, w8, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_int2:
; GISEL: // %bb.0:
; GISEL-NEXT: mul w0, w8, w8
; GISEL-NEXT: ret
%y1 = freeze i5 undef
%t1 = mul i5 %y1, %y1
ret i5 %t1
}

define float @freeze_float() {
; CHECK-LABEL: freeze_float:
; CHECK: // %bb.0:
; CHECK-NEXT: fadd s0, s0, s0
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_float:
; GISEL: // %bb.0:
; GISEL-NEXT: fadd s0, s0, s0
; GISEL-NEXT: ret
%y1 = freeze float undef
%t1 = fadd float %y1, %y1
ret float %t1
}

define <2 x i32> @freeze_ivec() {
; CHECK-LABEL: freeze_ivec:
; CHECK: // %bb.0:
; CHECK-NEXT: add v0.2s, v0.2s, v0.2s
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_ivec:
; GISEL: // %bb.0:
; GISEL-NEXT: add v0.2s, v0.2s, v0.2s
; GISEL-NEXT: ret
%y1 = freeze <2 x i32> undef
%t1 = add <2 x i32> %y1, %y1
ret <2 x i32> %t1
}

define i8* @freeze_ptr() {
; CHECK-LABEL: freeze_ptr:
; CHECK: // %bb.0:
; CHECK-NEXT: add x0, x8, #4 // =4
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_ptr:
; GISEL: // %bb.0:
; GISEL-NEXT: add x0, x8, #4 // =4
; GISEL-NEXT: ret
%y1 = freeze i8* undef
%t1 = getelementptr i8, i8* %y1, i64 4
ret i8* %t1
}

define i32 @freeze_struct() {
; CHECK-LABEL: freeze_struct:
; CHECK: // %bb.0:
; CHECK-NEXT: add w0, w8, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_struct:
; GISEL: // %bb.0:
; GISEL-NEXT: add w0, w8, w8
; GISEL-NEXT: ret
%y1 = freeze %struct.T undef
%v1 = extractvalue %struct.T %y1, 0
%v2 = extractvalue %struct.T %y1, 1
%t1 = add i32 %v1, %v2
ret i32 %t1
}

define i32 @freeze_anonstruct() {
; CHECK-LABEL: freeze_anonstruct:
; CHECK: // %bb.0:
; CHECK-NEXT: add w0, w8, w8
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_anonstruct:
; GISEL: // %bb.0:
; GISEL-NEXT: add w0, w8, w8
; GISEL-NEXT: ret
%y1 = freeze {i32, i32} undef
%v1 = extractvalue {i32, i32} %y1, 0
%v2 = extractvalue {i32, i32} %y1, 1
%t1 = add i32 %v1, %v2
ret i32 %t1
}

define i32 @freeze_anonstruct2() {
; CHECK-LABEL: freeze_anonstruct2:
; CHECK: // %bb.0:
; CHECK-NEXT: add w0, w8, w8, uxth
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_anonstruct2:
; GISEL: // %bb.0:
; GISEL-NEXT: add w0, w8, w8, uxth
; GISEL-NEXT: ret
%y1 = freeze {i32, i16} undef
%v1 = extractvalue {i32, i16} %y1, 0
%v2 = extractvalue {i32, i16} %y1, 1
%z2 = zext i16 %v2 to i32
%t1 = add i32 %v1, %z2
ret i32 %t1
}

define i64 @freeze_array() {
; CHECK-LABEL: freeze_array:
; CHECK: // %bb.0:
; CHECK-NEXT: add x0, x8, x8
; CHECK-NEXT: ret
;
; GISEL-LABEL: freeze_array:
; GISEL: // %bb.0:
; GISEL-NEXT: add x0, x8, x8
; GISEL-NEXT: ret
%y1 = freeze [2 x i64] undef
%v1 = extractvalue [2 x i64] %y1, 0
%v2 = extractvalue [2 x i64] %y1, 1
%t1 = add i64 %v1, %v2
ret i64 %t1
}
70 changes: 70 additions & 0 deletions llvm/test/CodeGen/AArch64/GlobalISel/legalize-freeze.mir
@@ -0,0 +1,70 @@
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
# RUN: llc -march=aarch64 -run-pass=legalizer -O0 %s -o - | FileCheck %s
---
name: test_freeze_s64
body: |
bb.0.entry:
liveins: $x0
; CHECK-LABEL: name: test_freeze_s64
; CHECK: %x0:_(s64) = COPY $x0
; CHECK: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE %x0
; CHECK: $x0 = COPY [[FREEZE]](s64)
%x0:_(s64) = COPY $x0
%1:_(s64) = G_FREEZE %x0
$x0 = COPY %1(s64)
...
---
name: test_freeze_v4s32
body: |
bb.0:
liveins: $q0
; CHECK-LABEL: name: test_freeze_v4s32
; CHECK: %q0:_(<4 x s32>) = COPY $q0
; CHECK: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE %q0
; CHECK: [[UV:%[0-9]+]]:_(<2 x s32>), [[UV1:%[0-9]+]]:_(<2 x s32>) = G_UNMERGE_VALUES [[FREEZE]](<4 x s32>)
; CHECK: $x0 = COPY [[UV]](<2 x s32>)
; CHECK: $x1 = COPY [[UV1]](<2 x s32>)
%q0:_(<4 x s32>) = COPY $q0
%0:_(<4 x s32>) = G_FREEZE %q0
%1:_(<2 x s32> ), %2:_(<2 x s32>) = G_UNMERGE_VALUES %0
$x0 = COPY %1
$x1 = COPY %2
...
---
name: test_freeze_v4s64
body: |
bb.0:
; CHECK-LABEL: name: test_freeze_v4s64
; CHECK: [[DEF:%[0-9]+]]:_(<2 x s64>) = G_IMPLICIT_DEF
; CHECK: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY [[DEF]](<2 x s64>)
; CHECK: [[FREEZE:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[DEF]]
; CHECK: [[FREEZE1:%[0-9]+]]:_(<2 x s64>) = G_FREEZE [[COPY]]
; CHECK: $q0 = COPY [[FREEZE]](<2 x s64>)
; CHECK: $q1 = COPY [[FREEZE1]](<2 x s64>)
%undef:_(<4 x s64>) = G_IMPLICIT_DEF
%0:_(<4 x s64>) = G_FREEZE %undef
%1:_(<2 x s64> ), %2:_(<2 x s64>) = G_UNMERGE_VALUES %0
$q0 = COPY %1
$q1 = COPY %2
...
---
name: test_freeze_v2s32
body: |
bb.0:
liveins: $d0
; CHECK-LABEL: name: test_freeze_v2s32
; CHECK: %d0:_(<2 x s32>) = COPY $d0
; CHECK: [[FREEZE:%[0-9]+]]:_(<2 x s32>) = G_FREEZE %d0
; CHECK: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[FREEZE]](<2 x s32>)
; CHECK: $w0 = COPY [[UV]](s32)
; CHECK: $w1 = COPY [[UV1]](s32)
%d0:_(<2 x s32>) = COPY $d0
%0:_(<2 x s32>) = G_FREEZE %d0
%1:_(s32), %2:_(s32) = G_UNMERGE_VALUES %0
$w0 = COPY %1
$w1 = COPY %2
...
Expand Up @@ -117,8 +117,9 @@
# DEBUG-NEXT: .. the first uncovered imm index: 0, OK
#
# DEBUG-NEXT: G_FREEZE (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. type index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. imm index coverage check SKIPPED: no rules defined
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
# DEBUG-NEXT: .. type index coverage check SKIPPED: user-defined predicate detected
# DEBUG-NEXT: .. imm index coverage check SKIPPED: user-defined predicate detected
#
# DEBUG-NEXT: G_INTRINSIC_TRUNC (opcode {{[0-9]+}}): 1 type index, 0 imm indices
# DEBUG-NEXT: .. opcode {{[0-9]+}} is aliased to {{[0-9]+}}
Expand Down

0 comments on commit 665da59

Please sign in to comment.