Skip to content

Commit eb8c408

Browse files
committedFeb 11, 2018
[TargetLowering] try to create -1 constant operand for math ops via demanded bits
This reverses instcombine's demanded bits' transform which always tries to clear bits in constants. As noted in PR35792 and shown in the test diffs: https://bugs.llvm.org/show_bug.cgi?id=35792 ...we can do better in codegen by trying to form -1. The x86 sub test shows a missed opportunity. I did investigate changing instcombine's behavior, but it would be more work to change canonicalization in IR. Clearing bits / shrinking constants can allow killing instructions, so we'd have to figure out how to not regress those cases. Differential Revision: https://reviews.llvm.org/D42986 llvm-svn: 324839
1 parent 7630150 commit eb8c408

File tree

4 files changed

+25
-7
lines changed

4 files changed

+25
-7
lines changed
 

‎llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,27 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
12321232
}
12331233
return true;
12341234
}
1235+
1236+
// If we have a constant operand, we may be able to turn it into -1 if we
1237+
// do not demand the high bits. This can make the constant smaller to
1238+
// encode, allow more general folding, or match specialized instruction
1239+
// patterns (eg, 'blsr' on x86). Don't bother changing 1 to -1 because that
1240+
// is probably not useful (and could be detrimental).
1241+
ConstantSDNode *C = isConstOrConstSplat(Op1);
1242+
APInt HighMask = APInt::getHighBitsSet(NewMask.getBitWidth(), NewMaskLZ);
1243+
if (C && !C->isAllOnesValue() && !C->isOne() &&
1244+
(C->getAPIntValue() | HighMask).isAllOnesValue()) {
1245+
SDValue Neg1 = TLO.DAG.getAllOnesConstant(dl, VT);
1246+
// We can't guarantee that the new math op doesn't wrap, so explicitly
1247+
// clear those flags to prevent folding with a potential existing node
1248+
// that has those flags set.
1249+
SDNodeFlags Flags;
1250+
Flags.setNoSignedWrap(false);
1251+
Flags.setNoUnsignedWrap(false);
1252+
SDValue NewOp = TLO.DAG.getNode(Op.getOpcode(), dl, VT, Op0, Neg1, Flags);
1253+
return TLO.CombineTo(Op, NewOp);
1254+
}
1255+
12351256
LLVM_FALLTHROUGH;
12361257
}
12371258
default:

‎llvm/test/CodeGen/AArch64/sub1.ll

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
define i64 @sub1_disguised_constant(i64 %x) {
55
; CHECK-LABEL: sub1_disguised_constant:
66
; CHECK: // %bb.0:
7-
; CHECK-NEXT: orr w8, wzr, #0xffff
8-
; CHECK-NEXT: add w8, w0, w8
7+
; CHECK-NEXT: sub w8, w0, #1 // =1
98
; CHECK-NEXT: and w8, w0, w8
109
; CHECK-NEXT: and x0, x8, #0xffff
1110
; CHECK-NEXT: ret

‎llvm/test/CodeGen/X86/bmi.ll

+1-2
Original file line numberDiff line numberDiff line change
@@ -813,8 +813,7 @@ define i64 @blsr64(i64 %x) {
813813
define i64 @blsr_disguised_constant(i64 %x) {
814814
; CHECK-LABEL: blsr_disguised_constant:
815815
; CHECK: # %bb.0:
816-
; CHECK-NEXT: leal 65535(%rdi), %eax
817-
; CHECK-NEXT: andl %edi, %eax
816+
; CHECK-NEXT: blsrl %edi, %eax
818817
; CHECK-NEXT: movzwl %ax, %eax
819818
; CHECK-NEXT: retq
820819
%a1 = and i64 %x, 65535

‎llvm/test/CodeGen/X86/zext-demanded.ll

+2-3
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ define i32 @test8(i32 %x) {
101101
define i64 @add_neg_one(i64 %x) {
102102
; CHECK-LABEL: add_neg_one:
103103
; CHECK: # %bb.0:
104-
; CHECK-NEXT: leal 65535(%rdi), %eax
104+
; CHECK-NEXT: leal -1(%rdi), %eax
105105
; CHECK-NEXT: andl %edi, %eax
106106
; CHECK-NEXT: movzwl %ax, %eax
107107
; CHECK-NEXT: retq
@@ -128,8 +128,7 @@ define i64 @mul_neg_one(i64 %x) {
128128
; CHECK-LABEL: mul_neg_one:
129129
; CHECK: # %bb.0:
130130
; CHECK-NEXT: movl %edi, %eax
131-
; CHECK-NEXT: shll $16, %eax
132-
; CHECK-NEXT: subl %edi, %eax
131+
; CHECK-NEXT: negl %eax
133132
; CHECK-NEXT: andl %edi, %eax
134133
; CHECK-NEXT: movzwl %ax, %eax
135134
; CHECK-NEXT: retq

0 commit comments

Comments
 (0)
Please sign in to comment.