[llvm] a841187 - [PowerPC] Enforce side effects to FPSCR read/set intrinsics
Qiu Chaofan via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 3 20:45:53 PDT 2021
Author: Qiu Chaofan
Date: 2021-11-04T11:45:32+08:00
New Revision: a84118756c73cbd736019f311d5d459b1e94c894
URL: https://github.com/llvm/llvm-project/commit/a84118756c73cbd736019f311d5d459b1e94c894
DIFF: https://github.com/llvm/llvm-project/commit/a84118756c73cbd736019f311d5d459b1e94c894.diff
LOG: [PowerPC] Enforce side effects to FPSCR read/set intrinsics
Currently, FPSCR is not modeled, so in some early passes (such as
early-cse), the read/set intrinsics to FPSCR may get incorrect
simplification.
Reviewed By: jsji
Differential Revision: https://reviews.llvm.org/D112380
Added:
Modified:
llvm/include/llvm/IR/IntrinsicsPowerPC.td
llvm/lib/Target/PowerPC/PPCInstrInfo.td
llvm/test/CodeGen/PowerPC/read-set-flm.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/IR/IntrinsicsPowerPC.td b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
index 8b158aa99de0..4161e3b8b0f2 100644
--- a/llvm/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/llvm/include/llvm/IR/IntrinsicsPowerPC.td
@@ -31,10 +31,12 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
// Get content from current FPSCR register
def int_ppc_readflm : GCCBuiltin<"__builtin_readflm">,
- Intrinsic<[llvm_double_ty], [], [IntrNoMem]>;
+ Intrinsic<[llvm_double_ty], [],
+ [IntrNoMerge, IntrHasSideEffects]>;
// Set FPSCR register, and return previous content
def int_ppc_setflm : GCCBuiltin<"__builtin_setflm">,
- Intrinsic<[llvm_double_ty], [llvm_double_ty], []>;
+ Intrinsic<[llvm_double_ty], [llvm_double_ty],
+ [IntrHasSideEffects]>;
// Intrinsics for [double]word extended forms of divide instructions
def int_ppc_divwe : GCCBuiltin<"__builtin_divwe">,
diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
index 22f64641ce28..3aaf5c389c8b 100644
--- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td
+++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td
@@ -3108,14 +3108,14 @@ def MTFSB1 : XForm_43<63, 38, (outs), (ins u5imm:$FM),
PPC970_DGroup_Single, PPC970_Unit_FPU;
}
-let Defs = [RM] in {
+let Defs = [RM], hasSideEffects = 1 in {
let isCodeGenOnly = 1 in
def MTFSFb : XFLForm<63, 711, (outs), (ins i32imm:$FM, f8rc:$rT),
"mtfsf $FM, $rT", IIC_IntMTFSB0,
[(int_ppc_mtfsf timm:$FM, f64:$rT)]>,
PPC970_DGroup_Single, PPC970_Unit_FPU;
}
-let Uses = [RM] in {
+let Uses = [RM], hasSideEffects = 1 in {
def MFFS : XForm_42<63, 583, (outs f8rc:$rT), (ins),
"mffs $rT", IIC_IntMFFS,
[(set f64:$rT, (PPCmffs))]>,
@@ -4503,7 +4503,7 @@ def MCRFS : XLForm_3<63, 64, (outs crrc:$BF), (ins crrc:$BFA),
// All MTFSF variants may change the rounding mode so conservatively set it
// as an implicit def for all of them.
let Predicates = [HasFPU] in {
-let Defs = [RM] in {
+let Defs = [RM], hasSideEffects = 1 in {
let isCodeGenOnly = 1,
Pattern = [(int_ppc_mtfsfi timm:$BF, timm:$U)], W = 0 in
def MTFSFIb : XLForm_4<63, 134, (outs), (ins u3imm:$BF, u4imm:$U),
diff --git a/llvm/test/CodeGen/PowerPC/read-set-flm.ll b/llvm/test/CodeGen/PowerPC/read-set-flm.ll
index aa651e14f203..1f4a905cd69e 100644
--- a/llvm/test/CodeGen/PowerPC/read-set-flm.ll
+++ b/llvm/test/CodeGen/PowerPC/read-set-flm.ll
@@ -11,6 +11,7 @@ define double @in_nostrict(double %a, double %b, double %c, double %d) {
; CHECK-NEXT: xsdivdp 1, 1, 2
; CHECK-NEXT: xsadddp 1, 1, 3
; CHECK-NEXT: xsadddp 0, 1, 0
+; CHECK-NEXT: mffs 1
; CHECK-NEXT: mtfsf 255, 4
; CHECK-NEXT: xsdivdp 1, 3, 4
; CHECK-NEXT: xsadddp 1, 1, 2
@@ -46,6 +47,7 @@ define double @in_strict(double %a, double %b, double %c, double %d) #0 {
; CHECK-NEXT: xsdivdp 1, 1, 2
; CHECK-NEXT: xsadddp 1, 1, 3
; CHECK-NEXT: xsadddp 0, 1, 0
+; CHECK-NEXT: mffs 1
; CHECK-NEXT: mtfsf 255, 4
; CHECK-NEXT: xsdivdp 1, 3, 4
; CHECK-NEXT: xsadddp 1, 1, 2
@@ -74,9 +76,88 @@ entry:
ret double %7
}
+define void @cse_nomerge(double* %f1, double* %f2, double %f3) #0 {
+; CHECK-LABEL: cse_nomerge:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mflr 0
+; CHECK-NEXT: .cfi_def_cfa_offset 64
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: .cfi_offset r30, -24
+; CHECK-NEXT: .cfi_offset f31, -8
+; CHECK-NEXT: std 30, -24(1) # 8-byte Folded Spill
+; CHECK-NEXT: stfd 31, -8(1) # 8-byte Folded Spill
+; CHECK-NEXT: std 0, 16(1)
+; CHECK-NEXT: stdu 1, -64(1)
+; CHECK-NEXT: fmr 31, 1
+; CHECK-NEXT: mr 30, 4
+; CHECK-NEXT: mffs 0
+; CHECK-NEXT: stfd 0, 0(3)
+; CHECK-NEXT: bl effect_func
+; CHECK-NEXT: nop
+; CHECK-NEXT: mffs 0
+; CHECK-NEXT: stfd 0, 0(30)
+; CHECK-NEXT: mffs 0
+; CHECK-NEXT: mtfsf 255, 31
+; CHECK-NEXT: addi 1, 1, 64
+; CHECK-NEXT: ld 0, 16(1)
+; CHECK-NEXT: lfd 31, -8(1) # 8-byte Folded Reload
+; CHECK-NEXT: ld 30, -24(1) # 8-byte Folded Reload
+; CHECK-NEXT: mtlr 0
+; CHECK-NEXT: blr
+entry:
+ %0 = call double @llvm.ppc.readflm()
+ store double %0, double* %f1, align 8
+ call void @effect_func()
+ %1 = call double @llvm.ppc.readflm()
+ store double %1, double* %f2, align 8
+ %2 = call contract double @llvm.ppc.setflm(double %f3)
+ ret void
+}
+
+define void @cse_nomerge_readonly(double* %f1, double* %f2, double %f3) #0 {
+; CHECK-LABEL: cse_nomerge_readonly:
+; CHECK: # %bb.0: # %entry
+; CHECK-NEXT: mflr 0
+; CHECK-NEXT: .cfi_def_cfa_offset 64
+; CHECK-NEXT: .cfi_offset lr, 16
+; CHECK-NEXT: .cfi_offset r30, -24
+; CHECK-NEXT: .cfi_offset f31, -8
+; CHECK-NEXT: std 30, -24(1) # 8-byte Folded Spill
+; CHECK-NEXT: stfd 31, -8(1) # 8-byte Folded Spill
+; CHECK-NEXT: std 0, 16(1)
+; CHECK-NEXT: stdu 1, -64(1)
+; CHECK-NEXT: fmr 31, 1
+; CHECK-NEXT: mr 30, 4
+; CHECK-NEXT: mffs 0
+; CHECK-NEXT: stfd 0, 0(3)
+; CHECK-NEXT: bl readonly_func
+; CHECK-NEXT: nop
+; CHECK-NEXT: mffs 0
+; CHECK-NEXT: stfd 0, 0(30)
+; CHECK-NEXT: mffs 0
+; CHECK-NEXT: mtfsf 255, 31
+; CHECK-NEXT: addi 1, 1, 64
+; CHECK-NEXT: ld 0, 16(1)
+; CHECK-NEXT: lfd 31, -8(1) # 8-byte Folded Reload
+; CHECK-NEXT: ld 30, -24(1) # 8-byte Folded Reload
+; CHECK-NEXT: mtlr 0
+; CHECK-NEXT: blr
+entry:
+ %0 = call double @llvm.ppc.readflm()
+ store double %0, double* %f1, align 8
+ call void @readonly_func()
+ %1 = call double @llvm.ppc.readflm()
+ store double %1, double* %f2, align 8
+ %2 = call contract double @llvm.ppc.setflm(double %f3)
+ ret void
+}
+
+declare void @effect_func()
+declare void @readonly_func() #1
declare double @llvm.ppc.readflm()
declare double @llvm.ppc.setflm(double)
declare double @llvm.experimental.constrained.fadd.f64(double, double, metadata, metadata)
declare double @llvm.experimental.constrained.fdiv.f64(double, double, metadata, metadata)
attributes #0 = { strictfp }
+attributes #1 = { readonly }
More information about the llvm-commits
mailing list