Skip to content

Commit ef40ae4

Browse files
authored
[SelectionDAG] Fix incorrect fold condition in foldSetCCWithFunnelShift. (llvm#137637)
Proposed by [2ed1598](llvm@2ed1598): `fshl X, (or X, Y), C ==/!= 0 --> or (srl Y, BW-C), X ==/!= 0` This transformation is valid when (C%Bitwidth) != 0 , as verified by [Alive2](https://alive2.llvm.org/ce/z/TQYM-m). Fixes llvm#136746
1 parent 5b91756 commit ef40ae4

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,11 +4462,14 @@ static SDValue foldSetCCWithFunnelShift(EVT VT, SDValue N0, SDValue N1,
44624462

44634463
unsigned BitWidth = N0.getScalarValueSizeInBits();
44644464
auto *ShAmtC = isConstOrConstSplat(N0.getOperand(2));
4465-
if (!ShAmtC || ShAmtC->getAPIntValue().uge(BitWidth))
4465+
if (!ShAmtC)
4466+
return SDValue();
4467+
4468+
uint64_t ShAmt = ShAmtC->getAPIntValue().urem(BitWidth);
4469+
if (ShAmt == 0)
44664470
return SDValue();
44674471

44684472
// Canonicalize fshr as fshl to reduce pattern-matching.
4469-
unsigned ShAmt = ShAmtC->getZExtValue();
44704473
if (N0.getOpcode() == ISD::FSHR)
44714474
ShAmt = BitWidth - ShAmt;
44724475

llvm/test/CodeGen/AArch64/setcc-fsh.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,27 @@ define i1 @fshl_or_ne_2(i32 %x, i32 %y) {
248248
%r = icmp ne i32 %f, 2
249249
ret i1 %r
250250
}
251+
252+
define i1 @fshr_0_or_eq_0(i16 %x, i16 %y) {
253+
; CHECK-LABEL: fshr_0_or_eq_0:
254+
; CHECK: // %bb.0:
255+
; CHECK-NEXT: tst w0, #0xffff
256+
; CHECK-NEXT: cset w0, eq
257+
; CHECK-NEXT: ret
258+
%or = or i16 %x, %y
259+
%f = call i16 @llvm.fshr.i16(i16 %or, i16 %x, i16 0)
260+
%r = icmp eq i16 %f, 0
261+
ret i1 %r
262+
}
263+
264+
define i1 @fshr_32_or_eq_0(i16 %x, i16 %y) {
265+
; CHECK-LABEL: fshr_32_or_eq_0:
266+
; CHECK: // %bb.0:
267+
; CHECK-NEXT: tst w0, #0xffff
268+
; CHECK-NEXT: cset w0, eq
269+
; CHECK-NEXT: ret
270+
%or = or i16 %x, %y
271+
%f = call i16 @llvm.fshr.i16(i16 %or, i16 %x, i16 32)
272+
%r = icmp eq i16 %f, 0
273+
ret i1 %r
274+
}

0 commit comments

Comments
 (0)