Skip to content

Commit dd5c520

Browse files
committed
[CPG][ARM] Optimize towards branch on zero in codegenprepare
This adds a simple fold into codegenprepare that converts comparison of branches towards comparison with zero if possible. For example: %c = icmp ult %x, 8 br %c, bla, blb %tc = lshr %x, 3 becomes %tc = lshr %x, 3 %c = icmp eq %tc, 0 br %c, bla, blb As a first order approximation, this can reduce the number of instructions needed to perform the branch as the shift is (often) needed anyway. At the moment this does not effect very much, as llvm tends to prefer the opposite form. But it can protect against regressions from commits like rG9423f78240a2. Simple cases of Add and Sub are added along with Shift, equally as the comparison to zero can often be folded with cpsr flags. Differential Revision: https://reviews.llvm.org/D101778
1 parent 6ae9893 commit dd5c520

File tree

6 files changed

+123
-64
lines changed

6 files changed

+123
-64
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,10 @@ class TargetLoweringBase {
613613
/// with instruction generated for signed comparison.
614614
virtual bool isEqualityCmpFoldedWithSignedCmp() const { return true; }
615615

616+
/// Return true if the heuristic to prefer icmp eq zero should be used in code
617+
/// gen prepare.
618+
virtual bool preferZeroCompareBranch() const { return false; }
619+
616620
/// Return true if it is safe to transform an integer-domain bitwise operation
617621
/// into the equivalent floating-point operation. This should be set to true
618622
/// if the target has IEEE-754-compliant fabs/fneg operations for the input

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7688,6 +7688,67 @@ static bool tryUnmergingGEPsAcrossIndirectBr(GetElementPtrInst *GEPI,
76887688
return true;
76897689
}
76907690

7691+
static bool optimizeBranch(BranchInst *Branch, const TargetLowering &TLI) {
7692+
// Try and convert
7693+
// %c = icmp ult %x, 8
7694+
// br %c, bla, blb
7695+
// %tc = lshr %x, 3
7696+
// to
7697+
// %tc = lshr %x, 3
7698+
// %c = icmp eq %tc, 0
7699+
// br %c, bla, blb
7700+
// Creating the cmp to zero can be better for the backend, especially if the
7701+
// lshr produces flags that can be used automatically.
7702+
if (!TLI.preferZeroCompareBranch() || !Branch->isConditional())
7703+
return false;
7704+
7705+
ICmpInst *Cmp = dyn_cast<ICmpInst>(Branch->getCondition());
7706+
if (!Cmp || !isa<ConstantInt>(Cmp->getOperand(1)) || !Cmp->hasOneUse())
7707+
return false;
7708+
7709+
Value *X = Cmp->getOperand(0);
7710+
APInt CmpC = cast<ConstantInt>(Cmp->getOperand(1))->getValue();
7711+
7712+
for (auto *U : X->users()) {
7713+
Instruction *UI = dyn_cast<Instruction>(U);
7714+
// A quick dominance check
7715+
if (!UI ||
7716+
(UI->getParent() != Branch->getParent() &&
7717+
UI->getParent() != Branch->getSuccessor(0) &&
7718+
UI->getParent() != Branch->getSuccessor(1)) ||
7719+
(UI->getParent() != Branch->getParent() &&
7720+
!UI->getParent()->getSinglePredecessor()))
7721+
continue;
7722+
7723+
if (CmpC.isPowerOf2() && Cmp->getPredicate() == ICmpInst::ICMP_ULT &&
7724+
match(UI, m_Shr(m_Specific(X), m_SpecificInt(CmpC.logBase2())))) {
7725+
IRBuilder<> Builder(Branch);
7726+
if (UI->getParent() != Branch->getParent())
7727+
UI->moveBefore(Branch);
7728+
Value *NewCmp = Builder.CreateCmp(ICmpInst::ICMP_EQ, UI,
7729+
ConstantInt::get(UI->getType(), 0));
7730+
LLVM_DEBUG(dbgs() << "Converting " << *Cmp << "\n");
7731+
LLVM_DEBUG(dbgs() << " to compare on zero: " << *NewCmp << "\n");
7732+
Cmp->replaceAllUsesWith(NewCmp);
7733+
return true;
7734+
}
7735+
if (Cmp->isEquality() &&
7736+
(match(UI, m_Add(m_Specific(X), m_SpecificInt(-CmpC))) ||
7737+
match(UI, m_Sub(m_Specific(X), m_SpecificInt(CmpC))))) {
7738+
IRBuilder<> Builder(Branch);
7739+
if (UI->getParent() != Branch->getParent())
7740+
UI->moveBefore(Branch);
7741+
Value *NewCmp = Builder.CreateCmp(Cmp->getPredicate(), UI,
7742+
ConstantInt::get(UI->getType(), 0));
7743+
LLVM_DEBUG(dbgs() << "Converting " << *Cmp << "\n");
7744+
LLVM_DEBUG(dbgs() << " to compare on zero: " << *NewCmp << "\n");
7745+
Cmp->replaceAllUsesWith(NewCmp);
7746+
return true;
7747+
}
7748+
}
7749+
return false;
7750+
}
7751+
76917752
bool CodeGenPrepare::optimizeInst(Instruction *I, bool &ModifiedDT) {
76927753
// Bail out if we inserted the instruction to prevent optimizations from
76937754
// stepping on each other's toes.
@@ -7849,6 +7910,8 @@ bool CodeGenPrepare::optimizeInst(Instruction *I, bool &ModifiedDT) {
78497910
return optimizeSwitchInst(cast<SwitchInst>(I));
78507911
case Instruction::ExtractElement:
78517912
return optimizeExtractElementInst(cast<ExtractElementInst>(I));
7913+
case Instruction::Br:
7914+
return optimizeBranch(cast<BranchInst>(I), *TLI);
78527915
}
78537916

78547917
return false;

llvm/lib/Target/ARM/ARMISelLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,8 @@ class VectorType;
573573

574574
Sched::Preference getSchedulingPreference(SDNode *N) const override;
575575

576+
bool preferZeroCompareBranch() const override { return true; }
577+
576578
bool
577579
isShuffleMaskLegal(ArrayRef<int> M, EVT VT) const override;
578580
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;

llvm/test/CodeGen/ARM/branch-on-zero.ll

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -96,29 +96,26 @@ while.end: ; preds = %while.body, %entry
9696
define i32 @test_lshr2(i32* nocapture %x, i32* nocapture readonly %y, i32 %n) {
9797
; CHECK-V6M-LABEL: test_lshr2:
9898
; CHECK-V6M: @ %bb.0: @ %entry
99-
; CHECK-V6M-NEXT: cmp r2, #4
100-
; CHECK-V6M-NEXT: blo .LBB1_3
101-
; CHECK-V6M-NEXT: @ %bb.1: @ %while.body.preheader
10299
; CHECK-V6M-NEXT: lsrs r2, r2, #2
103-
; CHECK-V6M-NEXT: .LBB1_2: @ %while.body
100+
; CHECK-V6M-NEXT: beq .LBB1_2
101+
; CHECK-V6M-NEXT: .LBB1_1: @ %while.body
104102
; CHECK-V6M-NEXT: @ =>This Inner Loop Header: Depth=1
105103
; CHECK-V6M-NEXT: ldm r1!, {r3}
106104
; CHECK-V6M-NEXT: lsls r3, r3, #1
107105
; CHECK-V6M-NEXT: stm r0!, {r3}
108106
; CHECK-V6M-NEXT: subs r2, r2, #1
109-
; CHECK-V6M-NEXT: bne .LBB1_2
110-
; CHECK-V6M-NEXT: .LBB1_3: @ %while.end
107+
; CHECK-V6M-NEXT: bne .LBB1_1
108+
; CHECK-V6M-NEXT: .LBB1_2: @ %while.end
111109
; CHECK-V6M-NEXT: movs r0, #0
112110
; CHECK-V6M-NEXT: bx lr
113111
;
114112
; CHECK-V7M-LABEL: test_lshr2:
115113
; CHECK-V7M: @ %bb.0: @ %entry
116-
; CHECK-V7M-NEXT: cmp r2, #4
117-
; CHECK-V7M-NEXT: blo .LBB1_3
114+
; CHECK-V7M-NEXT: lsrs r2, r2, #2
115+
; CHECK-V7M-NEXT: beq .LBB1_3
118116
; CHECK-V7M-NEXT: @ %bb.1: @ %while.body.preheader
119117
; CHECK-V7M-NEXT: subs r1, #4
120118
; CHECK-V7M-NEXT: subs r0, #4
121-
; CHECK-V7M-NEXT: lsrs r2, r2, #2
122119
; CHECK-V7M-NEXT: .LBB1_2: @ %while.body
123120
; CHECK-V7M-NEXT: @ =>This Inner Loop Header: Depth=1
124121
; CHECK-V7M-NEXT: ldr r3, [r1, #4]!
@@ -134,24 +131,23 @@ define i32 @test_lshr2(i32* nocapture %x, i32* nocapture readonly %y, i32 %n) {
134131
; CHECK-V81M: @ %bb.0: @ %entry
135132
; CHECK-V81M-NEXT: .save {r7, lr}
136133
; CHECK-V81M-NEXT: push {r7, lr}
137-
; CHECK-V81M-NEXT: cmp r2, #4
138-
; CHECK-V81M-NEXT: blo .LBB1_3
139-
; CHECK-V81M-NEXT: @ %bb.1: @ %while.body.preheader
140-
; CHECK-V81M-NEXT: lsr.w lr, r2, #2
141-
; CHECK-V81M-NEXT: .LBB1_2: @ %while.body
134+
; CHECK-V81M-NEXT: lsrs r2, r2, #2
135+
; CHECK-V81M-NEXT: wls lr, r2, .LBB1_2
136+
; CHECK-V81M-NEXT: .LBB1_1: @ %while.body
142137
; CHECK-V81M-NEXT: @ =>This Inner Loop Header: Depth=1
143138
; CHECK-V81M-NEXT: ldr r2, [r1], #4
144139
; CHECK-V81M-NEXT: lsls r2, r2, #1
145140
; CHECK-V81M-NEXT: str r2, [r0], #4
146-
; CHECK-V81M-NEXT: le lr, .LBB1_2
147-
; CHECK-V81M-NEXT: .LBB1_3: @ %while.end
141+
; CHECK-V81M-NEXT: le lr, .LBB1_1
142+
; CHECK-V81M-NEXT: .LBB1_2: @ %while.end
148143
; CHECK-V81M-NEXT: movs r0, #0
149144
; CHECK-V81M-NEXT: pop {r7, pc}
150145
;
151146
; CHECK-V7A-LABEL: test_lshr2:
152147
; CHECK-V7A: @ %bb.0: @ %entry
153-
; CHECK-V7A-NEXT: cmp r2, #4
154-
; CHECK-V7A-NEXT: blo .LBB1_3
148+
; CHECK-V7A-NEXT: mov r3, #0
149+
; CHECK-V7A-NEXT: cmp r3, r2, lsr #2
150+
; CHECK-V7A-NEXT: beq .LBB1_3
155151
; CHECK-V7A-NEXT: @ %bb.1: @ %while.body.preheader
156152
; CHECK-V7A-NEXT: lsr r2, r2, #2
157153
; CHECK-V7A-NEXT: .LBB1_2: @ %while.body

llvm/test/CodeGen/Thumb2/2010-02-11-phi-cycle.ll

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@ define i32 @test(i32 %n) nounwind {
77
; CHECK: @ %bb.0: @ %entry
88
; CHECK-NEXT: .save {r4, lr}
99
; CHECK-NEXT: push {r4, lr}
10-
; CHECK-NEXT: cmp r0, #1
10+
; CHECK-NEXT: subs r4, r0, #1
1111
; CHECK-NEXT: it eq
1212
; CHECK-NEXT: popeq {r4, pc}
13-
; CHECK-NEXT: .LBB0_1: @ %bb.nph
14-
; CHECK-NEXT: subs r4, r0, #1
15-
; CHECK-NEXT: .LBB0_2: @ %bb
13+
; CHECK-NEXT: .LBB0_1: @ %bb
1614
; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1
1715
; CHECK-NEXT: bl f
1816
; CHECK-NEXT: bl g
1917
; CHECK-NEXT: subs r4, #1
20-
; CHECK-NEXT: bne .LBB0_2
21-
; CHECK-NEXT: @ %bb.3: @ %return
18+
; CHECK-NEXT: bne .LBB0_1
19+
; CHECK-NEXT: @ %bb.2: @ %return
2220
; CHECK-NEXT: pop {r4, pc}
2321
entry:
2422
%0 = icmp eq i32 %n, 1 ; <i1> [#uses=1]
@@ -50,26 +48,22 @@ define i32 @test_dead_cycle(i32 %n) nounwind {
5048
; CHECK: @ %bb.0: @ %entry
5149
; CHECK-NEXT: .save {r4, lr}
5250
; CHECK-NEXT: push {r4, lr}
53-
; CHECK-NEXT: cmp r0, #1
51+
; CHECK-NEXT: subs r4, r0, #1
5452
; CHECK-NEXT: it eq
5553
; CHECK-NEXT: popeq {r4, pc}
56-
; CHECK-NEXT: .LBB1_1: @ %bb.nph
57-
; CHECK-NEXT: subs r4, r0, #1
58-
; CHECK-NEXT: b .LBB1_3
59-
; CHECK-NEXT: .LBB1_2: @ %bb2
60-
; CHECK-NEXT: @ in Loop: Header=BB1_3 Depth=1
61-
; CHECK-NEXT: subs r4, #1
62-
; CHECK-NEXT: beq .LBB1_5
63-
; CHECK-NEXT: .LBB1_3: @ %bb
54+
; CHECK-NEXT: .LBB1_1: @ %bb
6455
; CHECK-NEXT: @ =>This Inner Loop Header: Depth=1
6556
; CHECK-NEXT: cmp r4, #2
66-
; CHECK-NEXT: blt .LBB1_2
67-
; CHECK-NEXT: @ %bb.4: @ %bb1
68-
; CHECK-NEXT: @ in Loop: Header=BB1_3 Depth=1
57+
; CHECK-NEXT: blt .LBB1_3
58+
; CHECK-NEXT: @ %bb.2: @ %bb1
59+
; CHECK-NEXT: @ in Loop: Header=BB1_1 Depth=1
6960
; CHECK-NEXT: bl f
7061
; CHECK-NEXT: bl g
71-
; CHECK-NEXT: b .LBB1_2
72-
; CHECK-NEXT: .LBB1_5: @ %return
62+
; CHECK-NEXT: .LBB1_3: @ %bb2
63+
; CHECK-NEXT: @ in Loop: Header=BB1_1 Depth=1
64+
; CHECK-NEXT: subs r4, #1
65+
; CHECK-NEXT: bne .LBB1_1
66+
; CHECK-NEXT: @ %bb.4: @ %return
7367
; CHECK-NEXT: pop {r4, pc}
7468
entry:
7569
%0 = icmp eq i32 %n, 1 ; <i1> [#uses=1]

llvm/test/Transforms/CodeGenPrepare/ARM/branch-on-zero.ll

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ target triple = "thumbv8.1m.main-none-eabi"
77
define i32 @lshr3_then(i32 %a) {
88
; CHECK-LABEL: @lshr3_then(
99
; CHECK-NEXT: entry:
10-
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A:%.*]], 8
11-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
10+
; CHECK-NEXT: [[L:%.*]] = lshr i32 [[A:%.*]], 3
11+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[L]], 0
12+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
1213
; CHECK: then:
1314
; CHECK-NEXT: ret i32 0
1415
; CHECK: else:
15-
; CHECK-NEXT: [[L:%.*]] = lshr i32 [[A]], 3
1616
; CHECK-NEXT: ret i32 [[L]]
1717
;
1818
entry:
@@ -30,10 +30,10 @@ else:
3030
define i32 @lshr5_else(i32 %a) {
3131
; CHECK-LABEL: @lshr5_else(
3232
; CHECK-NEXT: entry:
33-
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A:%.*]], 32
34-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
33+
; CHECK-NEXT: [[L:%.*]] = lshr i32 [[A:%.*]], 5
34+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[L]], 0
35+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
3536
; CHECK: then:
36-
; CHECK-NEXT: [[L:%.*]] = lshr i32 [[A]], 5
3737
; CHECK-NEXT: ret i32 [[L]]
3838
; CHECK: else:
3939
; CHECK-NEXT: ret i32 0
@@ -54,8 +54,8 @@ define i32 @lshr2_entry(i32 %a) {
5454
; CHECK-LABEL: @lshr2_entry(
5555
; CHECK-NEXT: entry:
5656
; CHECK-NEXT: [[L:%.*]] = lshr i32 [[A:%.*]], 1
57-
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A]], 2
58-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
57+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[L]], 0
58+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
5959
; CHECK: then:
6060
; CHECK-NEXT: ret i32 [[L]]
6161
; CHECK: else:
@@ -99,10 +99,10 @@ else:
9999
define i32 @ashr5_else(i32 %a) {
100100
; CHECK-LABEL: @ashr5_else(
101101
; CHECK-NEXT: entry:
102-
; CHECK-NEXT: [[C:%.*]] = icmp ult i32 [[A:%.*]], 32
103-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
102+
; CHECK-NEXT: [[L:%.*]] = ashr i32 [[A:%.*]], 5
103+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[L]], 0
104+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
104105
; CHECK: then:
105-
; CHECK-NEXT: [[L:%.*]] = ashr i32 [[A]], 5
106106
; CHECK-NEXT: ret i32 [[L]]
107107
; CHECK: else:
108108
; CHECK-NEXT: ret i32 0
@@ -145,10 +145,10 @@ else:
145145
define i32 @addm10_then(i32 %a) {
146146
; CHECK-LABEL: @addm10_then(
147147
; CHECK-NEXT: entry:
148-
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A:%.*]], 10
149-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
148+
; CHECK-NEXT: [[L:%.*]] = add i32 [[A:%.*]], -10
149+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[L]], 0
150+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
150151
; CHECK: then:
151-
; CHECK-NEXT: [[L:%.*]] = add i32 [[A]], -10
152152
; CHECK-NEXT: ret i32 [[L]]
153153
; CHECK: else:
154154
; CHECK-NEXT: ret i32 0
@@ -191,12 +191,12 @@ else:
191191
define i32 @sub10_else(i32 %a) {
192192
; CHECK-LABEL: @sub10_else(
193193
; CHECK-NEXT: entry:
194-
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A:%.*]], 10
195-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
194+
; CHECK-NEXT: [[L:%.*]] = sub i32 [[A:%.*]], 10
195+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[L]], 0
196+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
196197
; CHECK: then:
197198
; CHECK-NEXT: ret i32 0
198199
; CHECK: else:
199-
; CHECK-NEXT: [[L:%.*]] = sub i32 [[A]], 10
200200
; CHECK-NEXT: ret i32 [[L]]
201201
;
202202
entry:
@@ -214,10 +214,10 @@ else:
214214
define i32 @subm10_then(i32 %a) {
215215
; CHECK-LABEL: @subm10_then(
216216
; CHECK-NEXT: entry:
217-
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A:%.*]], -10
218-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
217+
; CHECK-NEXT: [[L:%.*]] = sub i32 [[A:%.*]], -10
218+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i32 [[L]], 0
219+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
219220
; CHECK: then:
220-
; CHECK-NEXT: [[L:%.*]] = sub i32 [[A]], -10
221221
; CHECK-NEXT: ret i32 [[L]]
222222
; CHECK: else:
223223
; CHECK-NEXT: ret i32 0
@@ -237,12 +237,12 @@ else:
237237
define i64 @lshr64(i64 %a) {
238238
; CHECK-LABEL: @lshr64(
239239
; CHECK-NEXT: entry:
240-
; CHECK-NEXT: [[C:%.*]] = icmp ult i64 [[A:%.*]], 1099511627776
241-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
240+
; CHECK-NEXT: [[L:%.*]] = lshr i64 [[A:%.*]], 40
241+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i64 [[L]], 0
242+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
242243
; CHECK: then:
243244
; CHECK-NEXT: ret i64 0
244245
; CHECK: else:
245-
; CHECK-NEXT: [[L:%.*]] = lshr i64 [[A]], 40
246246
; CHECK-NEXT: ret i64 [[L]]
247247
;
248248
entry:
@@ -260,12 +260,12 @@ else:
260260
define i128 @lshr128(i128 %a) {
261261
; CHECK-LABEL: @lshr128(
262262
; CHECK-NEXT: entry:
263-
; CHECK-NEXT: [[C:%.*]] = icmp ult i128 [[A:%.*]], 36893488147419103232
264-
; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[ELSE:%.*]]
263+
; CHECK-NEXT: [[L:%.*]] = lshr i128 [[A:%.*]], 65
264+
; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i128 [[L]], 0
265+
; CHECK-NEXT: br i1 [[TMP0]], label [[THEN:%.*]], label [[ELSE:%.*]]
265266
; CHECK: then:
266267
; CHECK-NEXT: ret i128 0
267268
; CHECK: else:
268-
; CHECK-NEXT: [[L:%.*]] = lshr i128 [[A]], 65
269269
; CHECK-NEXT: ret i128 [[L]]
270270
;
271271
entry:

0 commit comments

Comments
 (0)