Skip to content

Commit 9deee6b

Browse files
committed
[SDAG] Don't transfer !range metadata without !noundef to SDAG (PR64589)
D141386 changed the semantics of !range metadata to return poison on violation. If !range is combined with !noundef, violation is immediate UB instead, matching the old semantics. In theory, these IR semantics should also carry over into SDAG. In practice, DAGCombine has at least one key transform that is invalid in the presence of poison, namely the conversion of logical and/or to bitwise and/or (https://github.com/llvm/llvm-project/blob/c7b537bf0923df05254f9fa4722b298eb8f4790d/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp#L11252). Ideally, we would fix this transform, but this will require substantial work to avoid codegen regressions. In the meantime, avoid transferring !range metadata without !noundef, effectively restoring the old !range metadata semantics on the SDAG layer. Fixes #64589. Differential Revision: https://reviews.llvm.org/D157685
1 parent ce25459 commit 9deee6b

14 files changed

+49
-35
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

+19-7
Original file line numberDiff line numberDiff line change
@@ -4156,6 +4156,18 @@ void SelectionDAGBuilder::visitAlloca(const AllocaInst &I) {
41564156
assert(FuncInfo.MF->getFrameInfo().hasVarSizedObjects());
41574157
}
41584158

4159+
static const MDNode *getRangeMetadata(const Instruction &I) {
4160+
// If !noundef is not present, then !range violation results in a poison
4161+
// value rather than immediate undefined behavior. In theory, transferring
4162+
// these annotations to SDAG is fine, but in practice there are key SDAG
4163+
// transforms that are known not to be poison-safe, such as folding logical
4164+
// and/or to bitwise and/or. For now, only transfer !range if !noundef is
4165+
// also present.
4166+
if (!I.hasMetadata(LLVMContext::MD_noundef))
4167+
return nullptr;
4168+
return I.getMetadata(LLVMContext::MD_range);
4169+
}
4170+
41594171
void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
41604172
if (I.isAtomic())
41614173
return visitAtomicLoad(I);
@@ -4188,7 +4200,7 @@ void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
41884200

41894201
Align Alignment = I.getAlign();
41904202
AAMDNodes AAInfo = I.getAAMetadata();
4191-
const MDNode *Ranges = I.getMetadata(LLVMContext::MD_range);
4203+
const MDNode *Ranges = getRangeMetadata(I);
41924204
bool isVolatile = I.isVolatile();
41934205
MachineMemOperand::Flags MMOFlags =
41944206
TLI.getLoadMemOperandFlags(I, DAG.getDataLayout(), AC, LibInfo);
@@ -4593,7 +4605,7 @@ void SelectionDAGBuilder::visitMaskedLoad(const CallInst &I, bool IsExpanding) {
45934605
Alignment = DAG.getEVTAlign(VT);
45944606

45954607
AAMDNodes AAInfo = I.getAAMetadata();
4596-
const MDNode *Ranges = I.getMetadata(LLVMContext::MD_range);
4608+
const MDNode *Ranges = getRangeMetadata(I);
45974609

45984610
// Do not serialize masked loads of constant memory with anything.
45994611
MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo);
@@ -4627,7 +4639,7 @@ void SelectionDAGBuilder::visitMaskedGather(const CallInst &I) {
46274639
->getMaybeAlignValue()
46284640
.value_or(DAG.getEVTAlign(VT.getScalarType()));
46294641

4630-
const MDNode *Ranges = I.getMetadata(LLVMContext::MD_range);
4642+
const MDNode *Ranges = getRangeMetadata(I);
46314643

46324644
SDValue Root = DAG.getRoot();
46334645
SDValue Base;
@@ -7632,7 +7644,7 @@ void SelectionDAGBuilder::visitVPLoad(
76327644
Value *PtrOperand = VPIntrin.getArgOperand(0);
76337645
MaybeAlign Alignment = VPIntrin.getPointerAlignment();
76347646
AAMDNodes AAInfo = VPIntrin.getAAMetadata();
7635-
const MDNode *Ranges = VPIntrin.getMetadata(LLVMContext::MD_range);
7647+
const MDNode *Ranges = getRangeMetadata(VPIntrin);
76367648
SDValue LD;
76377649
// Do not serialize variable-length loads of constant memory with
76387650
// anything.
@@ -7659,7 +7671,7 @@ void SelectionDAGBuilder::visitVPGather(
76597671
Value *PtrOperand = VPIntrin.getArgOperand(0);
76607672
MaybeAlign Alignment = VPIntrin.getPointerAlignment();
76617673
AAMDNodes AAInfo = VPIntrin.getAAMetadata();
7662-
const MDNode *Ranges = VPIntrin.getMetadata(LLVMContext::MD_range);
7674+
const MDNode *Ranges = getRangeMetadata(VPIntrin);
76637675
SDValue LD;
76647676
if (!Alignment)
76657677
Alignment = DAG.getEVTAlign(VT.getScalarType());
@@ -7766,7 +7778,7 @@ void SelectionDAGBuilder::visitVPStridedLoad(
77667778
if (!Alignment)
77677779
Alignment = DAG.getEVTAlign(VT.getScalarType());
77687780
AAMDNodes AAInfo = VPIntrin.getAAMetadata();
7769-
const MDNode *Ranges = VPIntrin.getMetadata(LLVMContext::MD_range);
7781+
const MDNode *Ranges = getRangeMetadata(VPIntrin);
77707782
MemoryLocation ML = MemoryLocation::getAfter(PtrOperand, AAInfo);
77717783
bool AddToChain = !AA || !AA->pointsToConstantMemory(ML);
77727784
SDValue InChain = AddToChain ? DAG.getRoot() : DAG.getEntryNode();
@@ -9613,7 +9625,7 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) {
96139625
SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
96149626
const Instruction &I,
96159627
SDValue Op) {
9616-
const MDNode *Range = I.getMetadata(LLVMContext::MD_range);
9628+
const MDNode *Range = getRangeMetadata(I);
96179629
if (!Range)
96189630
return Op;
96199631

llvm/lib/Target/ARM/ARMTargetTransformInfo.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ ARMTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
205205
ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0)),
206206
ConstantAsMetadata::get(ConstantInt::get(IntTy32, 0x10000))};
207207
II.setMetadata(LLVMContext::MD_range, MDNode::get(II.getContext(), M));
208+
II.setMetadata(LLVMContext::MD_noundef,
209+
MDNode::get(II.getContext(), std::nullopt));
208210
return ⅈ
209211
}
210212
break;

llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
; CHECK: ret
88
define i32 @test_call_known_max_range() #0 {
99
entry:
10-
%id = tail call i32 @foo(), !range !0
10+
%id = tail call i32 @foo(), !range !0, !noundef !{}
1111
%and = and i32 %id, 1023
1212
ret i32 %and
1313
}
@@ -18,7 +18,7 @@ entry:
1818
; CHECK: ret
1919
define i32 @test_call_known_trunc_1_bit_range() #0 {
2020
entry:
21-
%id = tail call i32 @foo(), !range !0
21+
%id = tail call i32 @foo(), !range !0, !noundef !{}
2222
%and = and i32 %id, 511
2323
ret i32 %and
2424
}
@@ -29,7 +29,7 @@ entry:
2929
; CHECK: ret
3030
define i32 @test_call_known_max_range_m1() #0 {
3131
entry:
32-
%id = tail call i32 @foo(), !range !1
32+
%id = tail call i32 @foo(), !range !1, !noundef !{}
3333
%and = and i32 %id, 255
3434
ret i32 %and
3535
}

llvm/test/CodeGen/AMDGPU/array-ptr-calc-i32.ll

+3-3
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ define amdgpu_kernel void @test_private_array_ptr_calc(ptr addrspace(1) noalias
3030
%tid = call i32 @llvm.amdgcn.mbcnt.hi(i32 -1, i32 %mbcnt.lo)
3131
%a_ptr = getelementptr inbounds i32, ptr addrspace(1) %inA, i32 %tid
3232
%b_ptr = getelementptr inbounds i32, ptr addrspace(1) %inB, i32 %tid
33-
%a = load i32, ptr addrspace(1) %a_ptr, !range !0
34-
%b = load i32, ptr addrspace(1) %b_ptr, !range !0
33+
%a = load i32, ptr addrspace(1) %a_ptr, !range !0, !noundef !{}
34+
%b = load i32, ptr addrspace(1) %b_ptr, !range !0, !noundef !{}
3535
%result = add i32 %a, %b
3636
%alloca_ptr = getelementptr inbounds [16 x i32], ptr addrspace(5) %alloca, i32 1, i32 %b
3737
store i32 %result, ptr addrspace(5) %alloca_ptr, align 4
3838
; Dummy call
3939
call void @llvm.amdgcn.s.barrier()
40-
%reload = load i32, ptr addrspace(5) %alloca_ptr, align 4, !range !0
40+
%reload = load i32, ptr addrspace(5) %alloca_ptr, align 4, !range !0, !noundef !{}
4141
%out_ptr = getelementptr inbounds i32, ptr addrspace(1) %out, i32 %tid
4242
store i32 %reload, ptr addrspace(1) %out_ptr, align 4
4343
ret void

llvm/test/CodeGen/AMDGPU/global-saddr-load.ll

+3-3
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,7 @@ define amdgpu_ps float @global_load_f32_saddr_zext_vgpr_range(ptr addrspace(1) i
13961396
; GFX11-NEXT: global_load_b32 v0, v0, s[2:3]
13971397
; GFX11-NEXT: s_waitcnt vmcnt(0)
13981398
; GFX11-NEXT: ; return to shader part epilog
1399-
%voffset = load i32, ptr addrspace(1) %voffset.ptr, !range !0
1399+
%voffset = load i32, ptr addrspace(1) %voffset.ptr, !range !0, !noundef !{}
14001400
%zext.offset = zext i32 %voffset to i64
14011401
%gep = getelementptr inbounds float, ptr addrspace(1) %sbase, i64 %zext.offset
14021402
%load = load float, ptr addrspace(1) %gep
@@ -1422,7 +1422,7 @@ define amdgpu_ps float @global_load_f32_saddr_zext_vgpr_range_imm_offset(ptr add
14221422
; GFX11-NEXT: global_load_b32 v0, v0, s[2:3] offset:400
14231423
; GFX11-NEXT: s_waitcnt vmcnt(0)
14241424
; GFX11-NEXT: ; return to shader part epilog
1425-
%voffset = load i32, ptr addrspace(1) %voffset.ptr, !range !0
1425+
%voffset = load i32, ptr addrspace(1) %voffset.ptr, !range !0, !noundef !{}
14261426
%zext.offset = zext i32 %voffset to i64
14271427
%gep0 = getelementptr inbounds float, ptr addrspace(1) %sbase, i64 %zext.offset
14281428
%gep1 = getelementptr inbounds float, ptr addrspace(1) %gep0, i64 100
@@ -1470,7 +1470,7 @@ define amdgpu_ps float @global_load_f32_saddr_zext_vgpr_range_too_large(ptr addr
14701470
; GFX11-NEXT: global_load_b32 v0, v[0:1], off
14711471
; GFX11-NEXT: s_waitcnt vmcnt(0)
14721472
; GFX11-NEXT: ; return to shader part epilog
1473-
%voffset = load i32, ptr addrspace(1) %voffset.ptr, !range !1
1473+
%voffset = load i32, ptr addrspace(1) %voffset.ptr, !range !1, !noundef !{}
14741474
%zext.offset = zext i32 %voffset to i64
14751475
%gep = getelementptr inbounds float, ptr addrspace(1) %sbase, i64 %zext.offset
14761476
%load = load float, ptr addrspace(1) %gep

llvm/test/CodeGen/AMDGPU/load-range-metadata-assert.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ define <2 x i32> @range_metata_sext_range_0_i24_i64_bitcast(ptr addrspace(1) %pt
88
; GCN-NEXT: global_load_dwordx2 v[0:1], v[0:1], off glc
99
; GCN-NEXT: s_waitcnt vmcnt(0)
1010
; GCN-NEXT: s_setpc_b64 s[30:31]
11-
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !0
11+
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !0, !noundef !{}
1212
%shl = shl i64 %val, 22
1313
%ashr = ashr i64 %shl, 22
1414
%cast = bitcast i64 %ashr to <2 x i32>

llvm/test/CodeGen/AMDGPU/load-range-metadata-sign-bits.ll

+9-9
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ define i32 @range_metadata_sext_i8_signed_range_i32(ptr addrspace(1) %ptr) {
88
; GCN-NEXT: global_load_dword v0, v[0:1], off glc
99
; GCN-NEXT: s_waitcnt vmcnt(0)
1010
; GCN-NEXT: s_setpc_b64 s[30:31]
11-
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !0 ; [-127, 128)
11+
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !0, !noundef !{} ; [-127, 128)
1212
%shl = shl i32 %val, 24
1313
%ashr = ashr i32 %shl, 24
1414
ret i32 %ashr
@@ -22,7 +22,7 @@ define i32 @range_metadata_sext_upper_range_limited_i32(ptr addrspace(1) %ptr) {
2222
; GCN-NEXT: s_waitcnt vmcnt(0)
2323
; GCN-NEXT: v_bfe_i32 v0, v0, 0, 8
2424
; GCN-NEXT: s_setpc_b64 s[30:31]
25-
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !1 ; [-127, 256)
25+
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !1, !noundef !{} ; [-127, 256)
2626
%shl = shl i32 %val, 24
2727
%ashr = ashr i32 %shl, 24
2828
ret i32 %ashr
@@ -50,7 +50,7 @@ define i32 @range_metadata_sext_i8_neg_neg_range_i32(ptr addrspace(1) %ptr) {
5050
; GCN-NEXT: s_waitcnt vmcnt(0)
5151
; GCN-NEXT: v_and_b32_e32 v0, 63, v0
5252
; GCN-NEXT: s_setpc_b64 s[30:31]
53-
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !3
53+
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !3, !noundef !{}
5454
%shl = shl i32 %val, 25
5555
%ashr = ashr i32 %shl, 25
5656
ret i32 %ashr
@@ -63,7 +63,7 @@ define i32 @range_metadata_sextload_i8_signed_range_i4_i32(ptr addrspace(1) %ptr
6363
; GCN-NEXT: global_load_sbyte v0, v[0:1], off glc
6464
; GCN-NEXT: s_waitcnt vmcnt(0)
6565
; GCN-NEXT: s_setpc_b64 s[30:31]
66-
%load = load volatile i8, ptr addrspace(1) %ptr, align 1, !range !4
66+
%load = load volatile i8, ptr addrspace(1) %ptr, align 1, !range !4, !noundef !{}
6767
%shl = shl i8 %load, 3
6868
%ashr = ashr i8 %shl, 3
6969
%ext = sext i8 %ashr to i32
@@ -78,7 +78,7 @@ define i25 @range_metadata_sext_i8_signed_range_i25(ptr addrspace(1) %ptr) {
7878
; GCN-NEXT: s_waitcnt vmcnt(0)
7979
; GCN-NEXT: v_bfe_i32 v0, v0, 0, 2
8080
; GCN-NEXT: s_setpc_b64 s[30:31]
81-
%val = load volatile i25, ptr addrspace(1) %ptr, align 4, !range !5
81+
%val = load volatile i25, ptr addrspace(1) %ptr, align 4, !range !5, !noundef !{}
8282
%shl = shl i25 %val, 23
8383
%ashr = ashr i25 %shl, 23
8484
ret i25 %ashr
@@ -91,7 +91,7 @@ define i32 @range_metadata_i32_neg1_to_1(ptr addrspace(1) %ptr) {
9191
; GCN-NEXT: global_load_dword v0, v[0:1], off glc
9292
; GCN-NEXT: s_waitcnt vmcnt(0)
9393
; GCN-NEXT: s_setpc_b64 s[30:31]
94-
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !6
94+
%val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !6, !noundef !{}
9595
%shl = shl i32 %val, 31
9696
%ashr = ashr i32 %shl, 31
9797
ret i32 %ashr
@@ -106,7 +106,7 @@ define i64 @range_metadata_sext_i8_signed_range_i64(ptr addrspace(1) %ptr) {
106106
; GCN-NEXT: v_lshlrev_b32_e32 v1, 23, v0
107107
; GCN-NEXT: v_ashrrev_i64 v[0:1], 55, v[0:1]
108108
; GCN-NEXT: s_setpc_b64 s[30:31]
109-
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !7
109+
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !7, !noundef !{}
110110
%shl = shl i64 %val, 55
111111
%ashr = ashr i64 %shl, 55
112112
ret i64 %ashr
@@ -119,7 +119,7 @@ define i64 @range_metadata_sext_i32_signed_range_i64(ptr addrspace(1) %ptr) {
119119
; GCN-NEXT: global_load_dwordx2 v[0:1], v[0:1], off glc
120120
; GCN-NEXT: s_waitcnt vmcnt(0)
121121
; GCN-NEXT: s_setpc_b64 s[30:31]
122-
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !7
122+
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !7, !noundef !{}
123123
%shl = shl i64 %val, 31
124124
%ashr = ashr i64 %shl, 31
125125
ret i64 %ashr
@@ -132,7 +132,7 @@ define i64 @range_metadata_sext_i33_signed_range_i64(ptr addrspace(1) %ptr) {
132132
; GCN-NEXT: global_load_dwordx2 v[0:1], v[0:1], off glc
133133
; GCN-NEXT: s_waitcnt vmcnt(0)
134134
; GCN-NEXT: s_setpc_b64 s[30:31]
135-
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !8
135+
%val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !8, !noundef !{}
136136
%shl = shl i64 %val, 30
137137
%ashr = ashr i64 %shl, 30
138138
ret i64 %ashr

llvm/test/CodeGen/PowerPC/BreakableToken-reduced.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ _ZNK4llvm9StringRef10startswithES0_.exit: ; preds = %entry._ZNK4llvm9Str
295295
%agg.tmp6.sroa.2.0..sroa_idx14 = getelementptr inbounds %"class.clang::format::BreakableStringLiteral", ptr %this, i64 0, i32 0, i32 3, i32 1
296296
%agg.tmp6.sroa.2.0.copyload = load i64, ptr %agg.tmp6.sroa.2.0..sroa_idx14, align 8
297297
%InPPDirective = getelementptr inbounds %"class.clang::format::BreakableStringLiteral", ptr %this, i64 0, i32 0, i32 0, i32 3
298-
%5 = load i8, ptr %InPPDirective, align 4, !tbaa !34, !range !39
298+
%5 = load i8, ptr %InPPDirective, align 4, !tbaa !34, !range !39, !noundef !{}
299299
%tobool = icmp ne i8 %5, 0
300300
%IndentLevel = getelementptr inbounds %"class.clang::format::BreakableStringLiteral", ptr %this, i64 0, i32 0, i32 0, i32 2
301301
%6 = load i32, ptr %IndentLevel, align 8, !tbaa !33

llvm/test/CodeGen/PowerPC/global-address-non-got-indirect-access.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
; CHECK-NEXT: plbz r3, _ZL13StaticBoolVar@PCREL(0), 1
3434
; CHECK-NEXT: blr
3535
entry:
36-
%0 = load i8, ptr @_ZL13StaticBoolVar, align 1, !range !0
36+
%0 = load i8, ptr @_ZL13StaticBoolVar, align 1, !range !0, !noundef !{}
3737
%tobool = icmp ne i8 %0, 0
3838
ret i1 %tobool
3939
}

llvm/test/CodeGen/X86/legalize-vec-assertzext.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ define i64 @split_assertzext(ptr %x) nounwind {
1111
; CHECK-NEXT: popq %rcx
1212
; CHECK-NEXT: vzeroupper
1313
; CHECK-NEXT: retq
14-
%e = call <16 x i64> @test(), !range !0
14+
%e = call <16 x i64> @test(), !range !0, !noundef !{}
1515
%d = extractelement <16 x i64> %e, i32 15
1616
ret i64 %d
1717
}
@@ -29,7 +29,7 @@ define i64 @widen_assertzext(ptr %x) nounwind {
2929
; CHECK-NEXT: popq %rcx
3030
; CHECK-NEXT: vzeroupper
3131
; CHECK-NEXT: retq
32-
%e = call <7 x i64> @test2(), !range !0
32+
%e = call <7 x i64> @test2(), !range !0, !noundef !{}
3333
%d = extractelement <7 x i64> %e, i32 6
3434
ret i64 %d
3535
}

llvm/test/CodeGen/X86/pr12360.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ define zeroext i1 @f1(ptr %x) {
88
; CHECK-NEXT: retq
99

1010
entry:
11-
%0 = load i8, ptr %x, align 1, !range !0
11+
%0 = load i8, ptr %x, align 1, !range !0, !noundef !{}
1212
%tobool = trunc i8 %0 to i1
1313
ret i1 %tobool
1414
}
@@ -20,7 +20,7 @@ define zeroext i1 @f2(ptr %x) {
2020
; CHECK-NEXT: retq
2121

2222
entry:
23-
%0 = load i8, ptr %x, align 1, !range !0
23+
%0 = load i8, ptr %x, align 1, !range !0, !noundef !{}
2424
%tobool = icmp ne i8 %0, 0
2525
ret i1 %tobool
2626
}

llvm/test/CodeGen/X86/pr48458.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ define i1 @foo(ptr %0) {
99
; CHECK-NEXT: sete %al
1010
; CHECK-NEXT: retq
1111
top:
12-
%1 = load i64, ptr %0, !range !0
12+
%1 = load i64, ptr %0, !range !0, !noundef !{}
1313
%2 = icmp ult i64 %1, 2147483648
1414
ret i1 %2
1515
}

llvm/test/CodeGen/X86/pr48888.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ define void @test(ptr %p) nounwind {
1010
; CHECK-NEXT: cmpl $2, %eax
1111
; CHECK-NEXT: retq
1212
bb:
13-
%i = load i64, ptr %p, align 8, !range !0
13+
%i = load i64, ptr %p, align 8, !range !0, !noundef !{}
1414
%i1 = and i64 %i, 6
1515
%i2 = icmp eq i64 %i1, 2
1616
br i1 %i2, label %bb3, label %bb5

llvm/test/CodeGen/X86/pr64589.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
22
; RUN: llc -mtriple=x86_64-- < %s | FileCheck %s
33

4-
; FIXME: This is a miscompile.
54
; It's not possible to directly or the two loads together, because this might
65
; propagate a poison value from the second load (which has !range but not
76
; !noundef).
@@ -10,6 +9,7 @@ define i8 @test(ptr %p) {
109
; CHECK: # %bb.0:
1110
; CHECK-NEXT: movzbl (%rdi), %eax
1211
; CHECK-NEXT: orb 1(%rdi), %al
12+
; CHECK-NEXT: setne %al
1313
; CHECK-NEXT: addb %al, %al
1414
; CHECK-NEXT: retq
1515
%v1 = load i8, ptr %p, align 4, !range !0, !noundef !{}

0 commit comments

Comments
 (0)