[llvm-bugs] [Bug 45511] New: [SystemZ] wrong-code resulting from storing / loading of i1
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Apr 13 02:28:49 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=45511
Bug ID: 45511
Summary: [SystemZ] wrong-code resulting from storing / loading
of i1
Product: libraries
Version: 10.0
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: Backend: SystemZ
Assignee: unassignedbugs at nondot.org
Reporter: paulsson at linux.vnet.ibm.com
CC: llvm-bugs at lists.llvm.org
Created attachment 23343
--> https://bugs.llvm.org/attachment.cgi?id=23343&action=edit
reduced test case (main with inlined functions)
This Csmith program:
int a = 0, b = 0, d = 0;
static int c = 2;
int *f = 0;
int *bPtr = &b;
long e = 0;
long* const ePtr = &e;
static void fn5() {
f = &c;
*bPtr = 0;
*f = 0;
}
int *fn6() {
*bPtr = 8;
*ePtr = (1 == -1L / (1 ^ ((unsigned) c)));
return &d;
}
int main() {
fn5();
f = fn6();
printf("checksum = %X\n", e);
}
should print '0', but clang -O3 prints '1'.
fn5() and fn6() get inlined into main:
Before ISel:
define dso_local signext i32 @main() local_unnamed_addr #0 {
entry:
%0 = load i32*, i32** @bPtr, align 8, !tbaa !2
store i1 true, i1* @c, align 4 ; i1:true
store i32 8, i32* %0, align 4, !tbaa !6
%.b = load i1, i1* @c, align 4 ; i1
%conv.i = select i1 %.b, i64 1, i64 3 ; -> i64 1
%div.i = sdiv i64 -1, %conv.i ; -1 / 1 -> -1
%cmp.i = icmp eq i64 %div.i, 1 ; -> false
%conv2.i = zext i1 %cmp.i to i64 ; -> i64 0
store i64 %conv2.i, i64* @e, align 8, !tbaa !8
store i32* @d, i32** @f, align 8, !tbaa !2
%call1 = tail call signext i32 (i8*, ...) @printf ... %conv2.i ...
ret i32 0
}
Initial selection DAG: %bb.0 'main:entry'
// 'true' is stored as 1, which is -1 if interpreted as signed.
...
t7: ch = store<(store 1 into @c, align 4)> t4:1, Constant:i1<-1>, ... : i1:1
t10: i1,ch = load<(dereferenceable load 1 from @c, align 4)> t9, ... : i1:1
t13: i64 = select t10, Constant:i64<1>, Constant:i64<3> : -> 1
t15: i64 = sdiv Constant:i64<-1>, t13 : -> -1
t17: i1 = setcc t15, Constant:i64<1>, seteq:ch : -> 0
t18: i64 = zero_extend t17 : -> 0
...
Optimized lowered selection DAG: %bb.0 'main:entry'
// Combined to load back c as a sign extended i1, which should mean -1 here.
...
t52: ch = store<(store 1 into @c, align 4)> t0, Constant:i1<-1>, ... : i1:1
t51: i64,ch = load<(dereferenceable load 1 from @c, align 4), sext from i1>
t9, ... : sext from i1:1 : -1
t17: i1 = setcc t51, Constant:i64<1>, seteq:ch : 0
t18: i64 = zero_extend t17 : 0
...
Type-legalized selection DAG: %bb.0 'main:entry'
// Storing i32:1, but loading sext from i1, so should still mean -1
...
t55: ch = store<(store 1 into @c, align 4), trunc to i1>
t0, Constant:i32<1>, ... : 1
t51: i64,ch = load<(dereferenceable load 1 from @c, align 4), sext from i1>
t9, ... : -1
t56: i32 = setcc t51, Constant:i64<1>, seteq:ch : 0
t57: i64 = any_extend t56 : 0
t58: i64 = and t57, Constant:i64<1> : -> 0
...
Optimized type-legalized selection DAG: %bb.0 'main:entry'
...
t56: i32 = setcc t63, Constant:i64<1>, seteq:ch : 0
t59: i64 = zero_extend t56 : 0
t55: ch = store<(store 1 into @c, align 4), trunc to i1>
t0, Constant:i32<1>, ...
t63: i64,ch = load<(dereferenceable load 1 from @c, align 4), sext from i1>
t60, ... : -1
...
Legalized selection DAG: %bb.0 'main:entry'
// Storing 1 as i8 should still work.
// Loading it back as zero-extended from i8 seems wrong (*)
// AssertZext from i1 also seems wrong.
// Now the loaded value is zero-extended to 1, and the comparison returns true
and 1 is selected instead of 0, which is wrong.
...
t88: i32 = AssertZext t86, ValueType:ch:i1
t68: i32 = SystemZISD::ICMP t88, Constant:i32<1>,
TargetConstant:i32<0> : true
t72: i32 = SystemZISD::SELECT_CCMASK Constant:i32<1>, Constant:i32<0>,
TargetConstant:i32<14>, TargetConstant:i32<8>, t68
t59: i64 = zero_extend t72 : 1
t73: ch = store<(store 1 into @c, align 4), trunc to i8>
t0, Constant:i32<1>, ... : 1
t86: i32,ch = load<(dereferenceable load 1 from @c, align 4), zext from i8>
t60, ... : 1 ! (*)
...
(*) adjustSubwordCmp() is converting this to a zext load. I suspect this check
to not be sufficient:
if (uint64_t(SignedValue) + (uint64_t(1) << (NumBits - 1)) > Mask)
return;
NumBits is 8, but the load is sign-extending from i1.
I tried commenting out adjustSubwordCmp() but the sign extension of the i1 by
the load is still altered and lost. Not sure exactly what is going wrong
here...
---
bin/llc -mtriple=s390x-linux-gnu -mcpu=z14 -o - ./main.f.ll -O3
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200413/468a0be5/attachment.html>
More information about the llvm-bugs
mailing list