-
Notifications
You must be signed in to change notification settings - Fork 15k
[PowerPC] Fix lowering when performing conditional jumps on f128 or f16 #125776
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
base: main
Are you sure you want to change the base?
Conversation
|
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
|
@llvm/pr-subscribers-backend-powerpc Author: None (liushuyu) ChangesThis pull request fixes the ppc-isel lowering when LLVM frontend IR contains a conditional jump right after a floating-point comparison that conditions on a target datalayout = "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512"
target triple = "powerpc64le-unknown-linux-gnu"
define fp128 @<!-- -->test_function(fp128 %0) {
%2 = fcmp ogt fp128 %0, 0xL00000000000000000000000000000000
%3 = icmp i1 %2, false
br i1 %3, label %5, label %4
4: ; preds = %1
ret fp128 0xL00000000000000000000000000000000
5: ; preds = %1
ret fp128 0xL00000000000000000000000000000000
}Full diff: https://github.com/llvm/llvm-project/pull/125776.diff 4 Files Affected:
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index bdc1ac7c7da5891..587ffe0520b05cf 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -223,6 +223,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i8, Expand);
}
+ setOperationAction(ISD::BR_CC, MVT::f16, Custom);
if (Subtarget.isISA3_0()) {
setLoadExtAction(ISD::EXTLOAD, MVT::f64, MVT::f16, Legal);
setLoadExtAction(ISD::EXTLOAD, MVT::f32, MVT::f16, Legal);
@@ -1309,7 +1310,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM,
setOperationAction(ISD::SETCC, MVT::f128, Custom);
setOperationAction(ISD::STRICT_FSETCC, MVT::f128, Custom);
setOperationAction(ISD::STRICT_FSETCCS, MVT::f128, Custom);
- setOperationAction(ISD::BR_CC, MVT::f128, Expand);
+ setOperationAction(ISD::BR_CC, MVT::f128, Custom);
// Lower following f128 select_cc pattern:
// select_cc x, y, tv, fv, cc -> select_cc (setcc x, y, cc), 0, tv, fv, NE
@@ -8218,6 +8219,36 @@ SDValue PPCTargetLowering::LowerTRUNCATEVector(SDValue Op,
return DAG.getVectorShuffle(WideVT, DL, Op1, Op2, ShuffV);
}
+SDValue PPCTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
+ SDValue Chain = Op.getOperand(0);
+ ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
+ SDValue LHS = Op.getOperand(2);
+ SDValue RHS = Op.getOperand(3);
+ SDValue Dest = Op.getOperand(4);
+ EVT LHSVT = LHS.getValueType();
+ SDLoc dl(Op);
+
+ // Soften the cc condition with libcall if it is fp128.
+ if (LHSVT == MVT::f128) {
+ assert(!Subtarget.hasP9Vector() &&
+ "BR_CC for f128 is already legal under Power9!");
+ softenSetCCOperands(DAG, LHSVT, LHS, RHS, CC, dl, LHS, RHS, Chain);
+ if (RHS.getNode())
+ LHS = DAG.getNode(ISD::BR_CC, dl, Op.getValueType(), Chain,
+ DAG.getCondCode(CC), LHS, RHS, Dest);
+ return LHS;
+ }
+
+ if (LHSVT == MVT::f16) {
+ LHS = DAG.getFPExtendOrRound(LHS, dl, MVT::f32);
+ RHS = DAG.getFPExtendOrRound(RHS, dl, MVT::f32);
+ return DAG.getNode(ISD::BR_CC, dl, Op.getValueType(), Chain,
+ DAG.getCondCode(CC), LHS, RHS, Dest);
+ }
+
+ assert(false && "Only f16 and f128 BR_CC lowering is handled here!");
+}
+
/// LowerSELECT_CC - Lower floating point select_cc's into fsel instruction when
/// possible.
SDValue PPCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
@@ -12122,6 +12153,7 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::STORE: return LowerSTORE(Op, DAG);
case ISD::TRUNCATE: return LowerTRUNCATE(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
+ case ISD::BR_CC: return LowerBR_CC(Op, DAG);
case ISD::STRICT_FP_TO_UINT:
case ISD::STRICT_FP_TO_SINT:
case ISD::FP_TO_UINT:
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.h b/llvm/lib/Target/PowerPC/PPCISelLowering.h
index 514329bbe92d7f5..c0efdf1d5c56102 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.h
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.h
@@ -1297,6 +1297,7 @@ namespace llvm {
SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerTRUNCATE(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
+ SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG,
const SDLoc &dl) const;
SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/test/CodeGen/PowerPC/f128-branch-cond.ll b/llvm/test/CodeGen/PowerPC/f128-branch-cond.ll
index 75c2bc7bc0fa05d..353b06e64fda56a 100644
--- a/llvm/test/CodeGen/PowerPC/f128-branch-cond.ll
+++ b/llvm/test/CodeGen/PowerPC/f128-branch-cond.ll
@@ -291,6 +291,61 @@ final:
ret i32 %result
}
+define i32 @test_choice5(fp128 %a) #0 {
+; LABEL: test_choice5
+; P8-LABEL: test_choice5:
+; P8: # %bb.0:
+; P8-NEXT: mflr 0
+; P8-NEXT: stdu 1, -32(1)
+; P8-NEXT: std 0, 48(1)
+; P8-NEXT: addis 3, 2, .LCPI4_0@toc@ha
+; P8-NEXT: addi 3, 3, .LCPI4_0@toc@l
+; P8-NEXT: lxvd2x 0, 0, 3
+; P8-NEXT: xxswapd 35, 0
+; P8-NEXT: bl __gtkf2
+; P8-NEXT: nop
+; P8-NEXT: # kill: def $r3 killed $r3 killed $x3
+; P8-NEXT: cmpwi 3, 0
+; P8-NEXT: bgt 0, .LBB4_2
+; P8-NEXT: b .LBB4_1
+; P8-NEXT: .LBB4_1: # %if.true
+; P8-NEXT: li 3, 1
+; P8-NEXT: addi 1, 1, 32
+; P8-NEXT: ld 0, 16(1)
+; P8-NEXT: mtlr 0
+; P8-NEXT: blr
+; P8-NEXT: .LBB4_2: # %if.false
+; P8-NEXT: li 3, 0
+; P8-NEXT: addi 1, 1, 32
+; P8-NEXT: ld 0, 16(1)
+; P8-NEXT: mtlr 0
+; P8-NEXT: blr
+;
+; P9-LABEL: test_choice5:
+; P9: # %bb.0:
+; P9-NEXT: addis 3, 2, .LCPI4_0@toc@ha
+; P9-NEXT: addi 3, 3, .LCPI4_0@toc@l
+; P9-NEXT: lxv 35, 0(3)
+; P9-NEXT: xscmpuqp 0, 2, 3
+; P9-NEXT: bgt 0, .LBB4_2
+; P9-NEXT: b .LBB4_1
+; P9-NEXT: .LBB4_1: # %if.true
+; P9-NEXT: li 3, 1
+; P9-NEXT: blr
+; P9-NEXT: .LBB4_2: # %if.false
+; P9-NEXT: li 3, 0
+; P9-NEXT: blr
+ %cmp = fcmp ogt fp128 %a, 0xL00000000000000000000000000000000
+ %not = icmp eq i1 %cmp, false
+ br i1 %not, label %if.true, label %if.false
+
+if.true:
+ ret i32 1
+
+if.false:
+ ret i32 0
+}
+
attributes #0 = { nounwind }
declare i32 @foo()
diff --git a/llvm/test/CodeGen/PowerPC/f16-branch-cond.ll b/llvm/test/CodeGen/PowerPC/f16-branch-cond.ll
new file mode 100644
index 000000000000000..190033f3e03765f
--- /dev/null
+++ b/llvm/test/CodeGen/PowerPC/f16-branch-cond.ll
@@ -0,0 +1,139 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=powerpc64le-unknown-linux -mcpu=pwr8 -O0 < %s | \
+; RUN: FileCheck %s -check-prefix=P8
+; RUN: llc -mtriple=powerpc64le-unknown-linux -mcpu=pwr9 -O0 < %s | \
+; RUN: FileCheck %s -check-prefix=P9
+
+define i32 @test_choice1(half %a) #0 {
+; P8-LABEL: test_choice1:
+; P8: # %bb.0:
+; P8-NEXT: mflr 0
+; P8-NEXT: stdu 1, -32(1)
+; P8-NEXT: std 0, 48(1)
+; P8-NEXT: bl __gnu_f2h_ieee
+; P8-NEXT: nop
+; P8-NEXT: clrldi 3, 3, 48
+; P8-NEXT: bl __gnu_h2f_ieee
+; P8-NEXT: nop
+; P8-NEXT: xxlxor 0, 0, 0
+; P8-NEXT: fcmpu 0, 1, 0
+; P8-NEXT: bgt 0, .LBB0_2
+; P8-NEXT: b .LBB0_1
+; P8-NEXT: .LBB0_1: # %if.true
+; P8-NEXT: li 3, 1
+; P8-NEXT: addi 1, 1, 32
+; P8-NEXT: ld 0, 16(1)
+; P8-NEXT: mtlr 0
+; P8-NEXT: blr
+; P8-NEXT: .LBB0_2: # %if.false
+; P8-NEXT: li 3, 0
+; P8-NEXT: addi 1, 1, 32
+; P8-NEXT: ld 0, 16(1)
+; P8-NEXT: mtlr 0
+; P8-NEXT: blr
+;
+; P9-LABEL: test_choice1:
+; P9: # %bb.0:
+; P9-NEXT: xscvdphp 0, 1
+; P9-NEXT: mffprwz 3, 0
+; P9-NEXT: clrlwi 3, 3, 16
+; P9-NEXT: mtfprwz 0, 3
+; P9-NEXT: xscvhpdp 0, 0
+; P9-NEXT: xxlxor 1, 1, 1
+; P9-NEXT: fcmpu 0, 0, 1
+; P9-NEXT: bgt 0, .LBB0_2
+; P9-NEXT: b .LBB0_1
+; P9-NEXT: .LBB0_1: # %if.true
+; P9-NEXT: li 3, 1
+; P9-NEXT: blr
+; P9-NEXT: .LBB0_2: # %if.false
+; P9-NEXT: li 3, 0
+; P9-NEXT: blr
+ %cmp = fcmp ogt half %a, 0.0
+ %not = icmp eq i1 %cmp, false
+ br i1 %not, label %if.true, label %if.false
+
+if.true:
+ ret i32 1
+
+if.false:
+ ret i32 0
+}
+
+define i32 @test_choice2(half %a, half %b) #0 {
+; P8-LABEL: test_choice2:
+; P8: # %bb.0:
+; P8-NEXT: mflr 0
+; P8-NEXT: stdu 1, -64(1)
+; P8-NEXT: std 0, 80(1)
+; P8-NEXT: li 3, 52
+; P8-NEXT: stxsspx 2, 1, 3 # 4-byte Folded Spill
+; P8-NEXT: fmr 0, 1
+; P8-NEXT: lxsspx 1, 1, 3 # 4-byte Folded Reload
+; P8-NEXT: li 3, 56
+; P8-NEXT: stxsspx 0, 1, 3 # 4-byte Folded Spill
+; P8-NEXT: bl __gnu_f2h_ieee
+; P8-NEXT: nop
+; P8-NEXT: clrldi 3, 3, 48
+; P8-NEXT: bl __gnu_h2f_ieee
+; P8-NEXT: nop
+; P8-NEXT: fmr 0, 1
+; P8-NEXT: li 3, 56
+; P8-NEXT: lxsspx 1, 1, 3 # 4-byte Folded Reload
+; P8-NEXT: stfs 0, 60(1) # 4-byte Folded Spill
+; P8-NEXT: bl __gnu_f2h_ieee
+; P8-NEXT: nop
+; P8-NEXT: clrldi 3, 3, 48
+; P8-NEXT: bl __gnu_h2f_ieee
+; P8-NEXT: nop
+; P8-NEXT: lfs 0, 60(1) # 4-byte Folded Reload
+; P8-NEXT: fcmpu 0, 1, 0
+; P8-NEXT: bne 0, .LBB1_2
+; P8-NEXT: b .LBB1_1
+; P8-NEXT: .LBB1_1: # %if.true
+; P8-NEXT: li 3, 1
+; P8-NEXT: addi 1, 1, 64
+; P8-NEXT: ld 0, 16(1)
+; P8-NEXT: mtlr 0
+; P8-NEXT: blr
+; P8-NEXT: .LBB1_2: # %if.false
+; P8-NEXT: li 3, 0
+; P8-NEXT: addi 1, 1, 64
+; P8-NEXT: ld 0, 16(1)
+; P8-NEXT: mtlr 0
+; P8-NEXT: blr
+;
+; P9-LABEL: test_choice2:
+; P9: # %bb.0:
+; P9-NEXT: fmr 0, 1
+; P9-NEXT: xscvdphp 1, 2
+; P9-NEXT: mffprwz 3, 1
+; P9-NEXT: clrlwi 3, 3, 16
+; P9-NEXT: mtfprwz 1, 3
+; P9-NEXT: xscvhpdp 1, 1
+; P9-NEXT: xscvdphp 0, 0
+; P9-NEXT: mffprwz 3, 0
+; P9-NEXT: clrlwi 3, 3, 16
+; P9-NEXT: mtfprwz 0, 3
+; P9-NEXT: xscvhpdp 0, 0
+; P9-NEXT: fcmpu 0, 0, 1
+; P9-NEXT: bne 0, .LBB1_2
+; P9-NEXT: b .LBB1_1
+; P9-NEXT: .LBB1_1: # %if.true
+; P9-NEXT: li 3, 1
+; P9-NEXT: blr
+; P9-NEXT: .LBB1_2: # %if.false
+; P9-NEXT: li 3, 0
+; P9-NEXT: blr
+ %cmp = fcmp une half %a, %b
+ %not = xor i1 %cmp, true
+ br i1 %not, label %if.true, label %if.false
+
+if.true:
+ ret i32 1
+
+if.false:
+ ret i32 0
+}
+
+attributes #0 = { nounwind }
|
You can test this locally with the following command:git-clang-format --diff 0572580dd040a81dc69b798e202550d51d17204a 4ab3c93da431f9146526831cb0193c40d1919459 --extensions cpp,h -- llvm/lib/Target/PowerPC/PPCISelLowering.cpp llvm/lib/Target/PowerPC/PPCISelLowering.hView the diff from clang-format here.diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 587ffe0520..3dd9f14635 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -12153,7 +12153,8 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::STORE: return LowerSTORE(Op, DAG);
case ISD::TRUNCATE: return LowerTRUNCATE(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
- case ISD::BR_CC: return LowerBR_CC(Op, DAG);
+ case ISD::BR_CC:
+ return LowerBR_CC(Op, DAG);
case ISD::STRICT_FP_TO_UINT:
case ISD::STRICT_FP_TO_SINT:
case ISD::FP_TO_UINT:
|
934e4c0 to
2937b2f
Compare
|
Ping |
|
Ping |
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 don't think that fixing this should involve custom lowering. This is either an issue with legalization or with DAGCombine.
|
To expand on my comment, I believe the issue here is that SetCC + BrCond get merged to BR_CC for a legal type, but then set SetCC + BR_CC gets optimized so it now works on an illegal type. We should either prevent that from happening (if the invariant is that we never create illegal BR_CC in the first place) or we need to actually be able to legalize that BR_CC. |
This pull request fixes the ppc-isel lowering when LLVM frontend IR contains a conditional jump right after a floating-point comparison that conditions on a
f128orf16: