Skip to content

Commit 3369101

Browse files
committedMar 22, 2019
[RISCV] Allow conversion of CC logic to bitwise logic
Indicates in the TargetLowering interface that conversions from CC logic to bitwise logic are allowed. Adds tests that show the benefit when optimization opportunities are detected. Also adds tests that show that when the optimization is not applied correct code is generated (but opportunities for other optimizations remain). Differential Revision: https://reviews.llvm.org/D59596 Patch by Luís Marques. llvm-svn: 356740
1 parent 1ed6a74 commit 3369101

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed
 

‎llvm/lib/Target/RISCV/RISCVISelLowering.h

+4
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ class RISCVTargetLowering : public TargetLowering {
9898
EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
9999
EVT VT) const override;
100100

101+
bool convertSetCCLogicToBitwiseLogic(EVT VT) const override {
102+
return VT.isScalarInteger();
103+
}
104+
101105
bool shouldInsertFencesForAtomic(const Instruction *I) const override {
102106
return isa<LoadInst>(I) || isa<StoreInst>(I);
103107
}
+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2+
; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3+
; RUN: | FileCheck %s -check-prefix=RV32I
4+
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
5+
; RUN: | FileCheck %s -check-prefix=RV64I
6+
7+
define i1 @and_icmp_eq(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
8+
; RV32I-LABEL: and_icmp_eq:
9+
; RV32I: # %bb.0:
10+
; RV32I-NEXT: xor a2, a2, a3
11+
; RV32I-NEXT: xor a0, a0, a1
12+
; RV32I-NEXT: or a0, a0, a2
13+
; RV32I-NEXT: seqz a0, a0
14+
; RV32I-NEXT: ret
15+
;
16+
; RV64I-LABEL: and_icmp_eq:
17+
; RV64I: # %bb.0:
18+
; RV64I-NEXT: xor a2, a2, a3
19+
; RV64I-NEXT: xor a0, a0, a1
20+
; RV64I-NEXT: or a0, a0, a2
21+
; RV64I-NEXT: slli a0, a0, 32
22+
; RV64I-NEXT: srli a0, a0, 32
23+
; RV64I-NEXT: seqz a0, a0
24+
; RV64I-NEXT: ret
25+
%cmp1 = icmp eq i32 %a, %b
26+
%cmp2 = icmp eq i32 %c, %d
27+
%and = and i1 %cmp1, %cmp2
28+
ret i1 %and
29+
}
30+
31+
define i1 @or_icmp_ne(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
32+
; RV32I-LABEL: or_icmp_ne:
33+
; RV32I: # %bb.0:
34+
; RV32I-NEXT: xor a2, a2, a3
35+
; RV32I-NEXT: xor a0, a0, a1
36+
; RV32I-NEXT: or a0, a0, a2
37+
; RV32I-NEXT: snez a0, a0
38+
; RV32I-NEXT: ret
39+
;
40+
; RV64I-LABEL: or_icmp_ne:
41+
; RV64I: # %bb.0:
42+
; RV64I-NEXT: xor a2, a2, a3
43+
; RV64I-NEXT: xor a0, a0, a1
44+
; RV64I-NEXT: or a0, a0, a2
45+
; RV64I-NEXT: slli a0, a0, 32
46+
; RV64I-NEXT: srli a0, a0, 32
47+
; RV64I-NEXT: snez a0, a0
48+
; RV64I-NEXT: ret
49+
%cmp1 = icmp ne i32 %a, %b
50+
%cmp2 = icmp ne i32 %c, %d
51+
%or = or i1 %cmp1, %cmp2
52+
ret i1 %or
53+
}
54+
55+
define i1 @or_icmps_const_1bit_diff(i64 %x) nounwind {
56+
; RV32I-LABEL: or_icmps_const_1bit_diff:
57+
; RV32I: # %bb.0:
58+
; RV32I-NEXT: addi a2, a0, -13
59+
; RV32I-NEXT: sltu a0, a2, a0
60+
; RV32I-NEXT: add a0, a1, a0
61+
; RV32I-NEXT: addi a0, a0, -1
62+
; RV32I-NEXT: andi a1, a2, -5
63+
; RV32I-NEXT: or a0, a1, a0
64+
; RV32I-NEXT: seqz a0, a0
65+
; RV32I-NEXT: ret
66+
;
67+
; RV64I-LABEL: or_icmps_const_1bit_diff:
68+
; RV64I: # %bb.0:
69+
; RV64I-NEXT: addi a0, a0, -13
70+
; RV64I-NEXT: andi a0, a0, -5
71+
; RV64I-NEXT: seqz a0, a0
72+
; RV64I-NEXT: ret
73+
%a = icmp eq i64 %x, 17
74+
%b = icmp eq i64 %x, 13
75+
%r = or i1 %a, %b
76+
ret i1 %r
77+
}
78+
79+
define i1 @and_icmps_const_1bit_diff(i32 %x) nounwind {
80+
; RV32I-LABEL: and_icmps_const_1bit_diff:
81+
; RV32I: # %bb.0:
82+
; RV32I-NEXT: addi a0, a0, -44
83+
; RV32I-NEXT: andi a0, a0, -17
84+
; RV32I-NEXT: snez a0, a0
85+
; RV32I-NEXT: ret
86+
;
87+
; RV64I-LABEL: and_icmps_const_1bit_diff:
88+
; RV64I: # %bb.0:
89+
; RV64I-NEXT: addi a0, a0, -44
90+
; RV64I-NEXT: addi a1, zero, 1
91+
; RV64I-NEXT: slli a1, a1, 32
92+
; RV64I-NEXT: addi a1, a1, -17
93+
; RV64I-NEXT: and a0, a0, a1
94+
; RV64I-NEXT: snez a0, a0
95+
; RV64I-NEXT: ret
96+
%a = icmp ne i32 %x, 44
97+
%b = icmp ne i32 %x, 60
98+
%r = and i1 %a, %b
99+
ret i1 %r
100+
}
101+
102+
define i1 @and_icmps_const_not1bit_diff(i32 %x) nounwind {
103+
; RV32I-LABEL: and_icmps_const_not1bit_diff:
104+
; RV32I: # %bb.0:
105+
; RV32I-NEXT: addi a1, zero, 44
106+
; RV32I-NEXT: xor a1, a0, a1
107+
; RV32I-NEXT: addi a2, zero, 92
108+
; RV32I-NEXT: xor a0, a0, a2
109+
; RV32I-NEXT: snez a0, a0
110+
; RV32I-NEXT: snez a1, a1
111+
; RV32I-NEXT: and a0, a1, a0
112+
; RV32I-NEXT: ret
113+
;
114+
; RV64I-LABEL: and_icmps_const_not1bit_diff:
115+
; RV64I: # %bb.0:
116+
; RV64I-NEXT: slli a0, a0, 32
117+
; RV64I-NEXT: srli a0, a0, 32
118+
; RV64I-NEXT: addi a1, zero, 44
119+
; RV64I-NEXT: xor a1, a0, a1
120+
; RV64I-NEXT: addi a2, zero, 92
121+
; RV64I-NEXT: xor a0, a0, a2
122+
; RV64I-NEXT: snez a0, a0
123+
; RV64I-NEXT: snez a1, a1
124+
; RV64I-NEXT: and a0, a1, a0
125+
; RV64I-NEXT: ret
126+
%a = icmp ne i32 %x, 44
127+
%b = icmp ne i32 %x, 92
128+
%r = and i1 %a, %b
129+
ret i1 %r
130+
}

0 commit comments

Comments
 (0)