Index: include/llvm/Target/GlobalISel/SelectionDAGCompat.td =================================================================== --- include/llvm/Target/GlobalISel/SelectionDAGCompat.td +++ include/llvm/Target/GlobalISel/SelectionDAGCompat.td @@ -91,6 +91,7 @@ def : GINodeEquiv; def : GINodeEquiv; def : GINodeEquiv; +def : GINodeEquiv; // Broadly speaking G_LOAD is equivalent to ISD::LOAD but there are some // complications that tablegen must take care of. For example, Predicates such Index: lib/Target/AArch64/AArch64LegalizerInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64LegalizerInfo.cpp +++ lib/Target/AArch64/AArch64LegalizerInfo.cpp @@ -124,7 +124,7 @@ getActionDefinitionsBuilder({G_FREM, G_FPOW}).libcallFor({s32, s64}); - getActionDefinitionsBuilder(G_FCEIL) + getActionDefinitionsBuilder({G_FCEIL, G_FABS}) // If we don't have full FP16 support, then scalarize the elements of // vectors containing fp16 types. .fewerElementsIf( Index: lib/Target/AArch64/AArch64RegisterBankInfo.cpp =================================================================== --- lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -397,6 +397,7 @@ case TargetOpcode::G_FSIN: case TargetOpcode::G_FLOG10: case TargetOpcode::G_FLOG: + case TargetOpcode::G_FABS: return true; } return false; Index: test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir =================================================================== --- test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir +++ test/CodeGen/AArch64/GlobalISel/legalizer-info-validation.mir @@ -292,7 +292,7 @@ # DEBUG: .. the first uncovered type index: 2, OK # # DEBUG-NEXT: G_FABS (opcode {{[0-9]+}}): 1 type index -# DEBUG: .. type index coverage check SKIPPED: no rules defined +# DEBUG: .. type index coverage check SKIPPED: user-defined predicate detected # # DEBUG-NEXT: G_GEP (opcode {{[0-9]+}}): 2 type indices # DEBUG: .. the first uncovered type index: 2, OK Index: test/CodeGen/AArch64/GlobalISel/select-fabs.mir =================================================================== --- /dev/null +++ test/CodeGen/AArch64/GlobalISel/select-fabs.mir @@ -0,0 +1,130 @@ +# RUN: llc -verify-machineinstrs -mtriple aarch64--- \ +# RUN: -run-pass=instruction-select -mattr=+fullfp16 -global-isel %s -o - \ +# RUN: | FileCheck %s +... +--- +name: fabs_float +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: fabs_float + ; CHECK: %{{[0-9]+}}:fpr32 = FABSSr %{{[0-9]+}} + liveins: $s0 + %0:fpr(s32) = COPY $s0 + %1:fpr(s32) = G_FABS %0 + $s0 = COPY %1(s32) + +... +--- +name: fabs_double +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: fabs_double + ; CHECK: %{{[0-9]+}}:fpr64 = FABSDr %{{[0-9]+}} + liveins: $d0 + %0:fpr(s64) = COPY $d0 + %1:fpr(s64) = G_FABS %0 + $d0 = COPY %1(s64) + +... +--- +name: fabs_v2f32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: fabs_v2f32 + ; CHECK: %{{[0-9]+}}:fpr64 = FABSv2f32 %{{[0-9]+}} + liveins: $d0 + %0:fpr(<2 x s32>) = COPY $d0 + %1:fpr(<2 x s32>) = G_FABS %0 + $d0 = COPY %1(<2 x s32>) + +... +--- +name: fabs_v4f32 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: fabs_v4f32 + ; CHECK: %{{[0-9]+}}:fpr128 = FABSv4f32 %{{[0-9]+}} + liveins: $q0 + %0:fpr(<4 x s32>) = COPY $q0 + %1:fpr(<4 x s32>) = G_FABS %0 + $q0 = COPY %1(<4 x s32>) + +... +--- +name: fabs_v2f64 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: fabs_v2f64 + ; CHECK: %{{[0-9]+}}:fpr128 = FABSv2f64 %{{[0-9]+}} + liveins: $q0 + %0:fpr(<2 x s64>) = COPY $q0 + %1:fpr(<2 x s64>) = G_FABS %0 + $q0 = COPY %1(<2 x s64>) + +... +--- +name: fabs_v4f16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: fabs_v4f16 + ; CHECK: %{{[0-9]+}}:fpr64 = FABSv4f16 %{{[0-9]+}} + liveins: $d0 + %0:fpr(<4 x s16>) = COPY $d0 + %1:fpr(<4 x s16>) = G_FABS %0 + $d0 = COPY %1(<4 x s16>) + +... +--- +name: fabs_v8f16 +legalized: true +regBankSelected: true +tracksRegLiveness: true +registers: + - { id: 0, class: fpr } + - { id: 1, class: fpr } +body: | + bb.0: + ; CHECK-LABEL: name: fabs_v8f16 + ; CHECK: %{{[0-9]+}}:fpr128 = FABSv8f16 %{{[0-9]+}} + liveins: $q0 + %0:fpr(<8 x s16>) = COPY $q0 + %1:fpr(<8 x s16>) = G_FABS %0 + $q0 = COPY %1(<8 x s16>) + +... Index: test/CodeGen/AArch64/arm64-vfloatintrinsics.ll =================================================================== --- test/CodeGen/AArch64/arm64-vfloatintrinsics.ll +++ test/CodeGen/AArch64/arm64-vfloatintrinsics.ll @@ -110,12 +110,20 @@ %1 = call %v4f16 @llvm.fma.v4f16(%v4f16 %a, %v4f16 %b, %v4f16 %c) ret %v4f16 %1 } + +; FALLBACK-NOT: remark{{.*}}test_v4f16.fabs define %v4f16 @test_v4f16.fabs(%v4f16 %a) { ; CHECK-LABEL: test_v4f16.fabs: ; CHECK-NOFP16-COUNT-4: fabs s{{[0-9]+}}, s{{[0-9]+}} ; CHECK-FP16-NOT: fcvt ; CHECK-FP16: fabs.4h ; CHECK-FP16-NEXT: ret + + ; GISEL-LABEL: test_v4f16.fabs: + ; GISEL-NOFP16-COUNT-4: fabs s{{[0-9]+}}, s{{[0-9]+}} + ; GISEL-FP16-NOT: fcvt + ; GISEL-FP16: fabs.4h + ; GISEL-FP16-NEXT: ret %1 = call %v4f16 @llvm.fabs.v4f16(%v4f16 %a) ret %v4f16 %1 } @@ -289,12 +297,20 @@ %1 = call %v8f16 @llvm.fma.v8f16(%v8f16 %a, %v8f16 %b, %v8f16 %c) ret %v8f16 %1 } + +; FALLBACK-NOT: remark{{.*}}test_v8f16.fabs define %v8f16 @test_v8f16.fabs(%v8f16 %a) { ; CHECK-LABEL: test_v8f16.fabs: ; CHECK-NOFP16-COUNT-8: fabs s{{[0-9]+}}, s{{[0-9]+}} ; CHECK-FP16-NOT: fcvt ; CHECK-FP16: fabs.8h ; CHECK-FP16-NEXT: ret + + ; GISEL-LABEL: test_v8f16.fabs: + ; GISEL-NOFP16-COUNT-8: fabs s{{[0-9]+}}, s{{[0-9]+}} + ; GISEL-FP16-NOT: fcvt + ; GISEL-FP16: fabs.8h + ; GISEL-FP16-NEXT: ret %1 = call %v8f16 @llvm.fabs.v8f16(%v8f16 %a) ret %v8f16 %1 } @@ -451,9 +467,13 @@ %1 = call %v2f32 @llvm.fma.v2f32(%v2f32 %a, %v2f32 %b, %v2f32 %c) ret %v2f32 %1 } + +; FALLBACK-NOT: remark{{.*}}test_v2f32.fabs ; CHECK-LABEL: test_v2f32.fabs: +; GISEL-LABEL: test_v2f32.fabs: define %v2f32 @test_v2f32.fabs(%v2f32 %a) { ; CHECK: fabs.2s + ; GISEL: fabs.2s %1 = call %v2f32 @llvm.fabs.v2f32(%v2f32 %a) ret %v2f32 %1 } @@ -591,9 +611,13 @@ %1 = call %v4f32 @llvm.fma.v4f32(%v4f32 %a, %v4f32 %b, %v4f32 %c) ret %v4f32 %1 } + +; FALLBACK-NOT: remark{{.*}}test_v4f32.fabs ; CHECK: test_v4f32.fabs: +; GISEL: test_v4f32.fabs: define %v4f32 @test_v4f32.fabs(%v4f32 %a) { ; CHECK: fabs + ; GISEL: fabs %1 = call %v4f32 @llvm.fabs.v4f32(%v4f32 %a) ret %v4f32 %1 } @@ -731,9 +755,13 @@ %1 = call %v2f64 @llvm.fma.v2f64(%v2f64 %a, %v2f64 %b, %v2f64 %c) ret %v2f64 %1 } + +; FALLBACK-NOT: remark{{.*}}test_v2f64.fabs ; CHECK: test_v2f64.fabs: +; GISEL: test_v2f64.fabs: define %v2f64 @test_v2f64.fabs(%v2f64 %a) { ; CHECK: fabs + ; GISEL: fabs %1 = call %v2f64 @llvm.fabs.v2f64(%v2f64 %a) ret %v2f64 %1 } Index: test/CodeGen/AArch64/f16-instructions.ll =================================================================== --- test/CodeGen/AArch64/f16-instructions.ll +++ test/CodeGen/AArch64/f16-instructions.ll @@ -991,6 +991,19 @@ ; CHECK-FP16-NEXT: fabs h0, h0 ; CHECK-FP16-NEXT: ret +; FALLBACK-NOT: remark:{{.*}}test_fabs +; FALLBACK-FP16-NOT: remark:{{.*}}test_fabs + +; GISEL-CVT-LABEL: test_fabs: +; GISEL-CVT-NEXT: fcvt s0, h0 +; GISEL-CVT-NEXT: fabs s0, s0 +; GISEL-CVT-NEXT: fcvt h0, s0 +; GISEL-CVT-NEXT: ret + +; GISEL-FP16-LABEL: test_fabs: +; GISEL-FP16-NEXT: fabs h0, h0 +; GISEL-FP16-NEXT: ret + define half @test_fabs(half %a) #0 { %r = call half @llvm.fabs.f16(half %a) ret half %r