| Issue |
174255
|
| Summary |
xor before constant table lookup should be optimized out
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
Validark
|
[Zig Godbolt](https://zig.godbo.lt/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:19,fontUsePx:'0',j:1,lang:zig,selection:(endColumn:3,endLineNumber:17,positionColumn:3,positionLineNumber:17,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:'export+fn+foo(x:+*Period)+u32+%7B%0A++++return+x.in_seconds()%3B%0A%7D%0A%0Aconst+Period+%3D+packed+struct(u8)+%7B%0A++++type:+enum(u2)+%7B+min,+hour,+day,+week+%7D,%0A++++duration:+u6,%0A%0A++++fn+in_seconds(self:+@This())+u32+%7B%0A++++++++return+self.duration+*+@as(u32,+switch+(self.type)+%7B%0A++++++++++++.min+%3D%3E+60,%0A++++++++++++.day+%3D%3E+24+*+60+*+60,%0A++++++++++++.hour+%3D%3E+60+*+60,%0A++++++++++++.week+%3D%3E+7+*+24+*+60+*+60,%0A++++++++%7D)%3B%0A++++%7D%0A%7D%3B'),l:'5',n:'0',o:'Zig+source+%231',t:'0')),k:50.37379893744152,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:z0152,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:19,fontUsePx:'0',j:2,lang:zig,libs:!(),options:'-target+x86_64-linux+-mcpu%3Dznver5+-fomit-frame-pointer+-O+ReleaseFast',overrides:!(),selection:(endColumn:20,endLineNumber:10,positionColumn:1,positionLineNumber:1,selectionStartColumn:20,selectionStartLineNumber:10,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+zig+0.15.2+(Editor+%231)',t:'0')),k:49.62620106255849,l:'4',m:100,n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4)
```zig
export fn foo(x: *Period) u32 {
return x.in_seconds();
}
const Period = packed struct(u8) {
type: enum(u2) { min, hour, day, week },
duration: u6,
fn in_seconds(self: @This()) u32 {
return self.duration * @as(u32, switch (self.type) {
.min => 60,
.day => 24 * 60 * 60,
.hour => 60 * 60,
.week => 7 * 24 * 60 * 60,
});
}
};
```
```asm
foo:
movzx eax, byte ptr [rdi]
mov ecx, eax
and ecx, 3
shr eax, 2
xor ecx, 2
imul eax, dword ptr [4*rcx + .Lswitch.table.foo]
ret
.Lswitch.table.foo:
.long 86400
.long 604800
.long 60
.long 3600
```
Obviously we can remove the xor by 2 if the table is re-arranged.
Here is the unoptimized LLVM IR dump from Zig:
```llvm
; ModuleID = 'main'
source_filename = "main"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux5.10.0-musl"
@builtin.zig_backend = internal unnamed_addr constant i64 2, align 8
@start.simplified_logic = internal unnamed_addr constant i1 false, align 1
@builtin.output_mode = internal unnamed_addr constant i2 -2, align 1
; Function Attrs: nounwind uwtable
define dso_local i32 @foo(ptr align 1 nonnull %0) #0 {
1:
%2 = alloca ptr, align 8
store ptr %0, ptr %2, align 8
%3 = load ptr, ptr %2, align 8
%4 = load i8, ptr %3, align 1
%5 = call fastcc i32 @main.Period.in_seconds(i8 %4)
ret i32 %5
}
; Function Attrs: nounwind uwtable
define internal fastcc i32 @main.Period.in_seconds(i8 %0) unnamed_addr #0 {
1:
%2 = lshr i8 %0, 2
%3 = trunc i8 %2 to i6
%4 = lshr i8 %0, 0
%5 = trunc i8 %4 to i2
switch i2 %5, label %14 [
i2 0, label %10
i2 -2, label %11
i2 1, label %12
i2 -1, label %13
]
6:
%7 = phi i32 [ 60, %10 ], [ 86400, %11 ], [ 3600, %12 ], [ 604800, %13 ]
%8 = zext i6 %3 to i32
%9 = mul nuw i32 %8, %7
ret i32 %9
10:
br label %6
11:
br label %6
12:
br label %6
13:
br label %6
14:
unreachable
}
attributes #0 = { nounwind uwtable "frame-pointer"="all" "target-cpu"="znver5" "target-features"="+64bit,+adx,+aes,+allow-light-256-bit,+avx,+avx2,+avx512bf16,+avx512bitalg,+avx512bw,+avx512cd,+avx512dq,+avx512f,+avx512ifma,+avx512vbmi,+avx512vbmi2,+avx512vl,+avx512vnni,+avx512vp2intersect,+avx512vpopcntdq,+avxvnni,+bmi,+bmi2,+branchfusion,+clflushopt,+clwb,+clzero,+cmov,+crc32,+cx16,+cx8,+evex512,+f16c,+fast-15bytenop,+fast-bextr,+fast-dpwssd,+fast-imm16,+fast-lzcnt,+fast-movbe,+fast-scalar-fsqrt,+fast-scalar-shift-masks,+fast-variable-perlane-shuffle,+fast-vector-fsqrt,+fma,+fsgsbase,+fsrm,+fxsr,+gfni,+idivq-to-divl,+invpcid,+lzcnt,+macrofusion,+mmx,+movbe,+movdir64b,+movdiri,+mwaitx,+nopl,+pclmul,+pku,+popcnt,+prefetchi,+prfchw,+rdpid,+rdpru,+rdrnd,+rdseed,+sahf,+sbb-dep-breaking,+sha,+shstk,+slow-shld,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+vaes,+vpclmulqdq,+vzeroupper,+wbnoinvd,+x87,+xsave,+xsavec,+xsaveopt,+xsaves,-16bit-mode,-32bit-mode,-amx-avx512,-amx-bf16,-amx-complex,-amx-fp16,-amx-fp8,-amx-int8,-amx-movrs,-amx-tf32,-amx-tile,-amx-transpose,-avx10.1-256,-avx10.1-512,-avx10.2-256,-avx10.2-512,-avx512fp16,-avxifma,-avxneconvert,-avxvnniint16,-avxvnniint8,-branch-hint,-ccmp,-cf,-cldemote,-cmpccxadd,-egpr,-enqcmd,-ermsb,-false-deps-getmant,-false-deps-lzcnt-tzcnt,-false-deps-mulc,-false-deps-mullq,-false-deps-perm,-false-deps-popcnt,-false-deps-range,-fast-11bytenop,-fast-7bytenop,-fast-gather,-fast-hops,-fast-shld-rotate,-fast-variable-crosslane-shuffle,-fast-vector-shift-masks,-faster-shift-than-shuffle,-fma4,-harden-sls-ijmp,-harden-sls-ret,-hreset,-idivl-to-divb,-inline-asm-use-gpr32,-kl,-lea-sp,-lea-uses-ag,-lvi-cfi,-lvi-load-hardening,-lwp,-movrs,-ndd,-nf,-no-bypass-delay,-no-bypass-delay-blend,-no-bypass-delay-mov,-no-bypass-delay-shuffle,-pad-short-functions,-pconfig,-ppx,-prefer-128-bit,-prefer-256-bit,-prefer-mask-registers,-prefer-movmsk-over-vtest,-prefer-no-gather,-prefer-no-scatter,-ptwrite,-push2pop2,-raoint,-retpoline,-retpoline-external-thunk,-retpoline-indirect-branches,-retpoline-indirect-calls,-rtm,-serialize,-seses,-sgx,-sha512,-slow-3ops-lea,-slow-incdec,-slow-lea,-slow-pmaddwd,-slow-pmulld,-slow-two-mem-ops,-slow-unaligned-mem-16,-slow-unaligned-mem-32,-sm3,-sm4,-soft-float,-sse-unaligned-mem,-tagged-globals,-tbm,-tsxldtrk,-tuning-fast-imm-vector-shift,-uintr,-use-glm-div-sqrt-costs,-use-slm-arith-costs,-usermsr,-waitpkg,-widekl,-xop,-zu" }
!llvm.module.flags = !{}
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs